bzoj3237 [Ahoi2013]连通图

link

 

题意:

给一张n个点m条边的无向图。Q次询问每次给一个大小为c的边集,问删去这些边后图是否还联通?

$n,m,Q\leq 2\times 10^5,c\leq 4.$

 

题解:

随机权值。

跑出任意一棵生成树,给每条非树边随机一个权值,每条树边的权值记为覆盖它的非树边的权值异或和。可以发现对于一个给定的边集合,如果有一个子集边权异或和为0,那么图必定不连通。判断是否存在子集异或和为0可以使用线性基。

复杂度$\mathcal{O}(n+30Qc)$。

 

code:

 1 #include<bits/stdc++.h>
 2 #define rep(i,x,y) for (int i=(x);i<=(y);i++)
 3 #define per(i,x,y) for (int i=(x);i>=(y);i--)
 4 #define ll long long
 5 #define inf 1000000001
 6 #define y1 y1___
 7 using namespace std;
 8 char gc(){
 9     static char buf[100000],*p1=buf,*p2=buf;
10     return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
11 }
12 #define gc getchar
13 ll read(){
14     char ch=gc();ll x=0;int op=1;
15     for (;!isdigit(ch);ch=gc()) if (ch=='-') op=-1;
16     for (;isdigit(ch);ch=gc()) x=(x<<1)+(x<<3)+ch-'0';
17     return x*op;
18 }
19 #define N 200005
20 int n,m,cnt,Q,clk,head[N],vis[N],w[N],a[35],w_[N];
21 struct edge{int to,nxt;}e[N<<1];
22 void adde(int x,int y){
23     e[++cnt].to=y;e[cnt].nxt=head[x];head[x]=cnt;
24 }
25 int Rnd(){
26     return rand()<<15|rand();
27 }
28 void dfs(int u,int pr){
29     vis[u]=++clk;
30     for (int i=head[u];i;i=e[i].nxt) if (e[i].to!=pr){
31         int v=e[i].to;
32         if (!vis[v]){
33             dfs(v,u);
34             w_[(i+1)/2]=w[v];
35             w[u]^=w[v];
36         } else if (vis[u]>vis[v]){
37             int tmp=Rnd();
38             w_[(i+1)/2]=tmp;
39             w[v]^=tmp;w[u]^=tmp;
40         }
41     }
42 }
43 bool ins(int x){
44     per (i,30,0) if (x>>i&1)
45         if (!a[i]) return a[i]=x,1;else x^=a[i];
46     return 0;
47 }
48 int main(){
49     srand(20030731);
50     n=read(),m=read();
51     rep (i,1,m){
52         int x=read(),y=read();
53         adde(x,y);adde(y,x);
54     }
55     dfs(1,0);
56     Q=read();
57     while (Q--){
58         bool flag=1;
59         for (int k=read();k;k--){
60             int x=read();
61             if (!ins(w_[x])) flag=0;
62         }
63         puts(flag?"Connected":"Disconnected");
64         rep (i,0,30) a[i]=0;
65     }
66     return 0;
67 }
View Code

 

posted @ 2018-08-01 16:11  bestfy  阅读(931)  评论(0编辑  收藏  举报