You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
77 lines
2.6 KiB
77 lines
2.6 KiB
/*
|
|
小A正在玩游戏,在游戏中一共有n个不同星球,星球间共有m条双向航道,小A的任务是摧毁这些星球。若有多个星球间两两可达,则我们称它们属于同一个联盟。特别的,若一个星球与其他星球间都没有航道,则也称其为一个联盟。小A将按照星球的编号从小到大依次摧毁各个星球,当一个星球被摧毁后,与之相连的航道也将相继被摧毁,现在小A想知道在每个星球被摧毁时还剩下多少个联盟。不同星球间可能有多条航道,但每条航道连接的两个星球必然不同。上述题意可以被简化为,给定n个点,m条边的无向图,按照编号大小依次删去各个节点,请问在每个节点被删去时,还剩下多少个连通块。保证给定图无自环,但可能有重边,
|
|
|
|
输入描述
|
|
第一行两个正整数n,m,表示星球数与航道数。接下来m行,每行2个正整数u,v,表示两星球间有一条航道。1<n,m<5e4
|
|
输出描述
|
|
输出一行n个正整数,表示答案。
|
|
|
|
样例输入
|
|
5 6
|
|
1 2
|
|
2 3
|
|
3 1
|
|
4 5
|
|
5 1
|
|
2 4
|
|
样例输出
|
|
1 2 1 1 0
|
|
*/
|
|
#include <stdio.h>
|
|
#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);
|
|
}
|
|
}
|