并查集,动态连通性

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

 

posted @ 2015-05-03 20:24  justPassBy  阅读(257)  评论(0编辑  收藏  举报