并查集,动态连通性

http://acm.csu.edu.cn/OnlineJudge/problem.php?cid=2079&pid=1

n,m代码n个点,m条边

随之而来m条边

q 代表q个操作

q行,每行一个序号,代表将第m个输入的边删除,问删除后有多少个连通块。

 

思路:我们将m条边,和q询问记录下来,并将要删除的边标记。

然后对那些不用的边使用并查集,并算出有多少个连通块。

然后从最后一个询问开始,依次将那些边加入并查集,如果加入时,两个点的父亲不同,那么连通块就减少一个

 

 1 #include <stdio.h> 

 2 #include <string.h> 

 3 #include <stdlib.h> 

 4 #include <algorithm> 

 5 #include <iostream> 

 6 #include <queue> 

 7 #include <stack> 

 8 #include <vector> 

 9 #include <map> 

10 #include <set> 

11 #include <string> 

12 #include <math.h> 

13 using namespace std;

14 #pragma warning(disable:4996) 

15 typedef long long LL;

16 const int INF = 1 << 30;

17 const int N = 100000 + 10;

18 int u[N], v[N], q[N];

19 int father[N];

20 int ans[N];

21 bool vis[N];

22 void init(int n)

23 {

24     for (int i = 0; i <= n; ++i)

25         father[i] = i;

26     memset(vis, 0, sizeof(vis));

27 }

28 int find(int x)

29 {

30     if (x == father[x])

31         return x;

32     return father[x] = find(father[x]);

33 }

34 int main()

35 {

36     int n, m, i, Q;

37     while (scanf("%d%d", &n, &m) != EOF)

38     {

39         init(n);

40         for (i = 1; i <= m; ++i)

41         {

42             scanf("%d%d", &u[i], &v[i]);

43         }

44         scanf("%d", &Q);

45         for (i = 0; i < Q; ++i)

46         {

47             scanf("%d", &q[i]);

48             vis[q[i]] = true;

49         }

50         for (i = 1; i <= m; ++i)

51         {

52             if (!vis[i])

53             {

54                 int rx = find(u[i]);

55                 int ry = find(v[i]);

56                 if (rx != ry)

57                     father[rx] = ry;

58             }

59         }

60         int tmp = 0;

61         for (i = 1; i <= n; ++i)

62         if (father[i] == i)//算出连通块

63             tmp++;

64         for (i = Q - 1; i >= 0; --i)//从后往前,加入那些要删除的边

65         {

66             int rx = find(u[q[i]]);

67             int ry = find(v[q[i]]);

68             ans[i] = tmp;//

69             if (rx != ry)

70             {

71                 father[rx] = ry;

72                 tmp--;

73             }

74 

75         }

76         for (i = 0; i < Q; ++i)

77             i == Q - 1 ? printf("%d\n", ans[i]) : printf("%d ", ans[i]);

78     }

79 }
View Code

 

你可能感兴趣的:(并查集)