大厂笔试题
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

/*
小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);
}
}