/* 小A正在玩游戏,在游戏中一共有n个不同星球,星球间共有m条双向航道,小A的任务是摧毁这些星球。若有多个星球间两两可达,则我们称它们属于同一个联盟。特别的,若一个星球与其他星球间都没有航道,则也称其为一个联盟。小A将按照星球的编号从小到大依次摧毁各个星球,当一个星球被摧毁后,与之相连的航道也将相继被摧毁,现在小A想知道在每个星球被摧毁时还剩下多少个联盟。不同星球间可能有多条航道,但每条航道连接的两个星球必然不同。上述题意可以被简化为,给定n个点,m条边的无向图,按照编号大小依次删去各个节点,请问在每个节点被删去时,还剩下多少个连通块。保证给定图无自环,但可能有重边, 输入描述 第一行两个正整数n,m,表示星球数与航道数。接下来m行,每行2个正整数u,v,表示两星球间有一条航道。1 #define MAXNUM 1000 int Group[MAXNUM]; //记录图中节点是否被访问过 int dist[MAXNUM][MAXNUM]; //通过邻接矩阵保存图 void DFS(int i, int n); int main() { int n, m, p, q, k = 0; for (int i = 0; i < MAXNUM; i++) { for (int j = 0; j < MAXNUM; j++) dist[i][j] = 0; //初始化邻接矩阵,初始值为0 Group[i] = 0; //同上 } scanf("%d%d", &n, &m); //获取图的节点数n,和边数m for (int i = 0; i < m; i++) { scanf("%d%d", &p, &q); dist[p-1][q-1] = 1; //如果节点1和节3相连 则另dist[1][3]和dist[3][1]的值为1 dist[q-1][p-1] = 1; } for(int zz = 1; zz <= n; zz++){ for(int j = 1; j <= n; j++){ // 删除节点zz相连的边 p = zz; q = j; dist[p-1][q-1] = 0; dist[q-1][p-1] = 0; } for (int i = 0; i < MAXNUM; i++) // 清零 { Group[i] = 0; } for (int i = 0; i < n; i++) { if (Group[i] != 1) { DFS(i, n); k++; //执行一次DFS就是k的值自增1, } } printf("%d", k - zz); // k为删除边但没有删除节点的连通数 zz表示每次删除一个节点 k = 0; } return 0; } void DFS(int i,int n) { Group[i] = 1; for (int j = 0; j < n; j++) { if (dist[i][j] == 1) if (Group[j] != 1) DFS(j, n); } }