【培训题】图的动态连通性

描述

  给出含n个点、m条边的无向图,结点编号为1..n。现在有4类操作:
  1、Link u v:在结点 u 和 v 之间连一条无向边。
  2、Query u v:查询 u 和 v 是否属于同一连通分量。
  3、Count 询问当前图的连通分量数。
  4、Max 询问当前最大的连同分量。

输入

  第一行:三个整数n,m,n,m的意义如题目描述。  接下来m行:每行两个数u,v(1<=u,v<=n),表示结点u和v之间有条无向边。 接着的一行是一个整数q,表示操作数。  再接下来q行:每行是题目描述中的四种操作之一。

输出

  输出每个查询的结果,对于Query u v 查询,如果u和v在同一连同分量中输出yEs,否则输出nO。

输入样例 1 

8 4
8 2
3 7
1 5
6 3
14
Count
Max
Link 3 2
Count
Max
Query 1 2
Link 6 8
Query 2 6
Count
Max
Link 1 3
Query 5 7
Count
Max

输出样例 1

4
3
3
5
nO
yEs
3
5
yEs
2
7

提示

n<=200000m<=200000q<=200000
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,m;
 4 const int maxn=0x3f3f3f;
 5 int pa[maxn];
 6 int sz[maxn];
 7 int Max=0,cnt=0;
 8 void makeset()
 9 {
10     for(int i=1;i<=n;i++)
11     {
12         pa[i]=i;
13         sz[i]=1;
14     }
15     cnt=n;
16     Max=1;
17 }
18 int Find(int x)
19 {
20     int r=x;
21     while(pa[r]!=r) 
22     r=pa[r];
23     
24     while(x!=r)
25     { 
26     int y=pa[x];
27     pa[x]=r;
28     x=y;
29     }
30     return r;
31 }
32 void Link(int x,int y)
33 {
34     int a=Find(x),b=Find(y);
35     if(a!=b)
36     {
37     pa[a]=b;
38     sz[b]+=sz[a];
39     Max=max(Max,sz[b]);
40     cnt--;
41     }
42 }
43 bool Query(int x,int y)
44 {
45     return Find(x)==Find(y);
46 }
47 int main()
48 {
49 
50     scanf("%d%d",&n,&m);
51     
52     makeset();
53     string s;
54     for(int i=1;i<=m;i++)
55     {
56         int x,y;
57         cin>>x>>y;
58         Link(x,y);
59     }
60     int t;
61     cin>>t;
62     while(t--)
63     {
64         cin>>s;
65         if(s=="Link")
66         {
67             int x,y;
68             scanf("%d%d",&x,&y);
69             Link(x,y);
70         }
71         if(s=="Query")
72         {
73             int x,y;
74             scanf("%d%d",&x,&y);
75             if(Query(x,y)==1)
76             printf("yEs\n");
77             else
78             printf("nO\n");
79         }
80         if(s=="Count")
81         {
82             printf("%d\n",cnt);
83         }
84         if(s=="Max")
85         {
86             printf("%d\n",Max);
87         }
88     }
89     return 0;
90 }

猜你喜欢

转载自www.cnblogs.com/poised/p/12109542.html