1. 程式人生 > >【BZOJ 3569】 DZY Loves Chinese II

【BZOJ 3569】 DZY Loves Chinese II

con 隔離 while ref 分享 spa 標記 break 圖片

題目連接:

  傳送門

題解:

  先%一發大佬的題解。

  考慮一個圖,刪除一些邊以後不連通的條件為,某個聯通塊與外界所有連邊都被刪掉,而不只是生成樹中一個樹邊與所以覆蓋它的非樹邊(很容易舉出反例)。

  那麽考慮如何才能判斷一個聯通塊與外界隔斷。

  先考慮只是一棵樹,那麽任意割一條邊都成立,那麽現在我們在這棵樹上加上一條邊(u,v),我們發現,在(u,v)以外的樹邊,割一條就成立,但在(u,v)覆蓋以內呢?

  如圖:  技術分享圖片

  我們發現我們可以把(u,v)與被(u,v)覆蓋的任意一條邊刪掉,但也可以把2向外連出,且被(u,v)覆蓋的邊給刪掉(即(1,2)、(2,3))。當我們把(2)看作一團點時我們可以發現以上條件也是成立的。

  以此類推我們可以發現被覆蓋的樹邊刪除後不再聯通的條件為:1.刪除其本身,同時將覆蓋其的邊刪掉;2.刪除其本身,將與其一同被覆蓋的其他樹邊刪掉。

  也就是說,產生新聯通塊的必要條件為:刪掉一條樹邊的同時,與其具有相同屬性的邊也被刪掉。

  那麽這個相同屬性是什麽:覆蓋邊的屬性。我們用一個數來表示覆蓋邊的屬性,也就是說我們刪除的集合要滿足刪除邊的屬性異或和為0,同時不能為空集!

  還是如上圖,我們把(1,3)的邊用x表示,我們給(2,3)、(1,2),即被覆蓋邊都打上x的標記,那麽我們發現刪除這三者中的任意二者都是成立的,因為x這個屬性,被gank了兩次,也就意味著這個覆蓋邊的貢獻在我們刪掉的邊之間的聯通塊(假想塊),與覆蓋邊以外的聯通塊隔離。

  所以我們隨機一個數給非樹邊作為它的屬性,那麽刪邊形成新聯通的條件就是刪邊集合中,存在一個子集(不含空集)的屬性異或和為0。

代碼:

 1 #include "bits/stdc++.h"
 2 
 3 using namespace std;
 4 
 5 inline int read() {
 6     int s=0,k=1;char ch=getchar();
 7     while (ch<0|ch>9) ch==-?k=-1:0,ch=getchar();
 8     while (ch>47&ch<=9) s=s*10
+(ch^48),ch=getchar(); 9 return s*k; 10 } 11 12 const int N=5e5+10,mod=1e9; 13 14 struct edges{ 15 int v;edges *last; 16 }edge[N*2],*head[N];int cnt=1; 17 18 inline void push(int u,int v){ 19 edge[++cnt]=(edges){v,head[u]},head[u]=edge+cnt; 20 } 21 22 struct node { 23 int x,y,val; 24 }ed[N]; 25 26 bool vis[N],used[N];int fat[N],val[N]; 27 28 inline void dfs(int x,int fa){ 29 vis[x]=true; 30 for (edges *i=head[x];i;i=i->last) if(i->v!=fa&&!vis[i->v]){ 31 fat[i->v]=x;used[i-edge>>1]=true; 32 dfs(i->v,x); 33 } 34 } 35 36 inline void dfs2(int x,int fa){ 37 for (edges *i=head[x];i;i=i->last) if(fat[i->v]==x){ 38 dfs2(i->v,x); 39 val[x]^=val[i->v]; 40 ed[i-edge>>1].val^=val[i->v]; 41 } 42 } 43 44 int n,m,b[40],bin[40]; 45 46 int main() { 47 srand(20000820); 48 n=read(),m=read(); 49 register int i,j,k; 50 for (i=1;i<=m;++i) ed[i].x=read(),ed[i].y=read(),push(ed[i].x,ed[i].y),push(ed[i].y,ed[i].x); 51 dfs(1,0); 52 for (i=1;i<=m;++i) if(!used[i]){ 53 int x=1ll*rand()*rand()%mod+1; 54 ed[i].val=x; 55 val[ed[i].x]^=x; 56 val[ed[i].y]^=x; 57 } 58 dfs2(1,0); 59 int Q=read(),num,x,ans=0; 60 for (i=0;i<=30;++i) bin[i]=1<<i; 61 while (Q--){ 62 num=read(); 63 memset(b,0,sizeof(b)); 64 bool flag=true; 65 for (i=1;i<=num;++i){ 66 x=read()^ans;x=ed[x].val; 67 for (j=30;~j;--j) if(x&bin[j]){ 68 if(b[j]) x^=b[j]; 69 else { 70 b[j]=x; 71 for (k=j-1;~k;--k) if(b[k]&&(bin[k]&b[j])) b[j]^=b[k]; 72 for (k=j+1;j<=30;++j) if(b[k]&bin[j]) b[k]^=b[j]; 73 break; 74 } 75 } 76 if(x==0) flag=false; 77 } 78 ans+=flag; 79 puts(flag?"Connected":"Disconnected"); 80 } 81 }

【BZOJ 3569】 DZY Loves Chinese II