[BZOJ3237]连通图

Description

Input

Output

Sample Input

4 5
1 2
2 3
3 4
4 1
2 4
3
1 5
2 2 3
2 1 2

Sample Output

Connected
Disconnected
Connected

HINT

N<=100000 M<=200000 K<=100000

自己yy的奇怪解法,首先我们可以发现一张图在联通的时候并查集祖先的$size=n$(这不是废话)

然后就只要线段树分治随便维护一下并查集就完事了

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<vector>
 5 #include<map>
 6 #define ls node<<1
 7 #define rs node<<1|1
 8 #define M 200010
 9 #define mod 1000000007
10 using namespace std;
11 struct point{int u,v;}p[M],st[M];
12 int n,m,k,top;
13 int size[M],fa[M],f[M];
14 vector<int>tag[M<<2];
15 int find(int x) {
16     while(x!=fa[x]) x=fa[x];
17     return fa[x];
18 }
19 void insert(int node,int l,int r,int l1,int r1,int id) {
20     if(l1<=l&&r1>=r) {
21         tag[node].push_back(id);return;
22     }int mid=(l+r)/2;
23     if(l1<=mid) insert(ls,l,mid,l1,r1,id);
24     if(r1>mid) insert(rs,mid+1,r,l1,r1,id);
25 }
26 void unionn(int x,int y) {
27     x=find(x),y=find(y);
28     if(x==y) return;
29     if(size[x]<size[y]) swap(x,y);
30     st[++top]=(point){x,y};
31     size[fa[y]=x]+=size[y];
32 }
33 void Del(int now) {
34     while(top!=now) {
35         int x=st[top].u,y=st[top--].v;
36         size[x]-=size[fa[y]=y];
37     }
38 }
39 void Dfs(int node,int l,int r) {
40     int now=top;
41     for(int i=0;i<tag[node].size();i++)
42         unionn(p[tag[node][i]].u,p[tag[node][i]].v);
43     if(l==r) {
44         int x=1;
45         while(fa[x]!=x) x=fa[x];
46         puts(size[x]==n?"Connected":"Disconnected");
47     }
48     else {
49         int mid=(l+r)/2;
50         Dfs(ls,l,mid),Dfs(rs,mid+1,r);
51     }
52     Del(now);
53 }
54 int main() {
55     scanf("%d%d",&n,&m);
56     for(int i=1;i<=n;i++) fa[i]=i,size[i]=1;
57     for(int a,b,i=1;i<=m;i++) {
58         scanf("%d%d",&a,&b);f[i]=1;
59         p[i]=(point){a,b};
60     }
61     scanf("%d",&k);
62     for(int i=1;i<=k;i++) {
63         int c;scanf("%d",&c);
64         for(int j=1;j<=c;j++) {
65             int id;scanf("%d",&id);
66             if(f[id]!=i) insert(1,1,k,f[id],i-1,id);
67             f[id]=i+1;
68         }
69     }
70     for(int i=1;i<=m;i++)
71         if(f[i]!=k+1)
72             insert(1,1,k,f[i],k,i);
73     Dfs(1,1,k);
74     return 0;
75 }

 

posted @ 2018-11-30 09:37  Slr  阅读(169)  评论(0编辑  收藏  举报