破坏城市
时间限制:
1000 ms | 内存限制:
65535 KB
难度:
3
-
描述
-
L 是一个坏蛋,他总是破坏遇见的一切事情。
一天,L到达一个新的城市,该城市有n个点,有m条线路来连接这n个点。L将破坏所有的线路。但是他想知道当他破坏前i条线路时该城市有多少个块组成。我们认为当两个点可以通过线路直接或间接相互到达时,这两点属于同一个块
-
输入
-
多组数据。
每组数据第一行输入 n ,m。(点的编号从0开始)。
接下来m行,每行输入两个数u,v,代表这两点有一条线路相连。
0 < n <= 10000
0 < m <= 100000
0 <= u, v < n.
输出
-
每组测试数据输出m行。
第i行表示当破坏前i个路线该城市块数。
样例输入
-
5 10
-
0 1
-
1 2
-
1 3
-
1 4
-
0 2
-
2 3
-
0 4
-
0 3
-
3 4
-
2 4
样例输出
-
1
-
1
-
1
-
2
-
2
-
2
-
2
-
3
-
4
-
5
-
//题目描述的很坑, 其实就是倒着插入的并查集 #include <stdio.h> #include <string.h> typedef struct ROAD { int a, b; }Road; int father[10001], ans[100001]; Road road[100001]; int findFather(int x) { if(father[x] == x) { return x; } return father[x] = findFather(father[x]); } int main() { int i, m, n, a, b; while(scanf("%d%d", &n, &m) != EOF) { for(i = 0; i < n; i++) //初始化 { father[i] = i; } for(i = 0; i < m; i++) { scanf("%d%d", &road[i].a, &road[i].b); } for(i = m-1; i >= 0; i--) //逆向插入并查集并记录结果 { a = findFather(road[i].a); b = findFather(road[i].b); if(a != b) { father[a] = b; ans[i] = n--; //记录结果,若有合并则n-- } else { ans[i] = n; } } for(i = 0; i < m; i++) //打印结果 { printf("%d\n", ans[i]); } } return 0; }
-
多组数据。