種類並查集
阿新 • • 發佈:2017-06-22
poj str 給定 fin problem div style find nod
一般的並查集是維護屬於同一種類的元素,對於屬於不同種類的元素之間的關系沒有記錄。種類並查集就是同一集合中的元素是已經確定關系的(是否屬於同一種類),然後加一個group數組,記錄一下孩子和父親是否屬於同一種類,遞推稍稍改一下就可以了。
poj1703:http://poj.org/problem?id=1703
題目大意:有n個罪犯,兩個幫派,已知其中若幹對兩者屬於不同幫派,求給定的罪犯是否屬於同一幫派。
需要註意,給的兩個罪犯可能已經在同一個集合裏了,需要處理一下,不然就無限遞歸了。。。
1 #include<iostream> 2 #include<cstring> 3#include<cstdio> 4 using namespace std; 5 const int maxn=1e5+5; 6 int p[maxn],group[maxn],n,m; 7 int Find(int x){ 8 if(p[x]==x)return x; 9 int t=Find(p[x]); 10 group[x]=group[x]==group[p[x]]?1:0; 11 return p[x]=t; 12 } 13 void Unit(int a,int b){ 14 int x=Find(a),y=Find(b);15 if(x==y)return; 16 p[x]=b; 17 group[x]=1^group[a]; 18 } 19 int Is_same(int a,int b){ 20 int x=Find(a),y=Find(b); 21 if(x!=y)return -1; 22 return group[a]==group[b]; 23 } 24 int main(){ 25 int t,a,b; 26 char c; 27 scanf("%d",&t); 28 while(t--){ 29 scanf("\n%d%d",&n,&m); 30 for(int i=0;i<n;i++){p[i]=i;group[i]=1;} 31 for(int i=0;i<m;i++){ 32 scanf("\n%c%d%d",&c,&a,&b); 33 a--;b--; 34 if(c==‘D‘){ 35 Unit(a,b); 36 }else{ 37 int t=Is_same(a,b); 38 if(t==-1)printf("Not sure yet.\n"); 39 else if(t==0)printf("In different gangs.\n"); 40 else if(t==1)printf("In the same gang.\n"); 41 } 42 } 43 } 44 return 0; 45 }
51nod 1204 Parity
分析:記前k個的和的奇偶性為f[k],若[a,b]和為偶數,則f[a]==f[b],否則f[a]!=f[b],然後用種類並查集維護一下就可以了。
1 #include<iostream> 2 #include<string> 3 using namespace std; 4 const int maxn=100005; 5 int p[maxn],group[maxn],n,q; 6 int Find(int x){ 7 if(p[x]==x)return x; 8 Find(p[x]); 9 group[x]=group[p[x]]==group[x]?1:0; 10 p[x]=Find(p[x]); 11 return p[x]; 12 } 13 int main(){ 14 cin>>n>>q; 15 for(int i=0;i<=n;i++){p[i]=i;group[i]=1;} 16 int a,b,ans=-1; 17 char s[10]; 18 for(int i=0;i<q;i++){ 19 cin>>a>>b>>s; 20 int x=Find(a-1),y=Find(b); 21 if(s[0]==‘e‘){ 22 if(x==y&&group[a-1]!=group[b]&&ans==-1) 23 ans=i+1; 24 if(x!=y){ 25 p[x]=y; 26 group[x]=group[a-1]==group[b]?1:0; 27 } 28 }else{ 29 if(x==y&&group[a-1]==group[b]&&ans==-1) 30 ans=i+1; 31 if(x!=y){ 32 p[x]=y; 33 group[x]=group[a-1]==group[b]?0:1; 34 } 35 } 36 } 37 cout<<ans<<endl; 38 return 0; 39 }
種類並查集