bzoj1077 -- 并查集
Posted gjghfd
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj1077 -- 并查集相关的知识,希望对你有一定的参考价值。
看这位大佬的题解就可以了。
http://blog.csdn.net/Fuxey/article/details/50573495
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<vector> 6 using namespace std; 7 #define N 60 8 int i,j,k,n,m,f[N],g[N][N],x,y,A,B,c[N],Cnt,l[N],r[N],a[N],Ans[3],a1,a2,a3,a4,X,Y,b[N],k1,k2,p[3],M; 9 bool f1,f2,Flag; 10 char s[N][N]; 11 inline int Find(int x){return f[x]==x?x:f[x]=Find(f[x]);} 12 int main(){ 13 scanf("%d%d%d",&n,&A,&B);M=n; 14 for(i=1;i<=n;i++)f[i]=i; 15 for(i=1;i<=n;i++){ 16 scanf("%s",s[i]+1); 17 for(j=1;j<=n;j++) 18 if(s[i][j]==‘=‘)f[Find(i)]=Find(j); 19 } 20 for(i=1;i<=n;i++) 21 for(j=1;j<=n;j++) 22 if(s[i][j]==‘+‘)g[Find(i)][Find(j)]=1,g[Find(j)][Find(i)]=-1;else 23 if(s[i][j]==‘-‘)g[Find(i)][Find(j)]=-1,g[Find(j)][Find(i)]=1; 24 for(i=1;i<=n;i++)if(Find(i)==i)c[++Cnt]=i; 25 for(n=Cnt,i=1;i<=n;i++){ 26 f1=f2=0; 27 for(j=1;j<=n;j++) 28 if(g[c[i]][c[j]]==1)f1=1;else if(g[c[i]][c[j]]==-1)f2=1; 29 if(!f1||!f2)continue; 30 for(a[c[i]]=2,j=1;j<=n;j++) 31 if(g[c[i]][c[j]]==1)a[c[j]]=1;else 32 if(g[c[i]][c[j]]==-1)a[c[j]]=3; 33 } 34 for(i=1;i<=n;i++){ 35 x=c[i]; 36 if(a[x])l[x]=r[x]=a[x];else{ 37 l[x]=1,r[x]=3; 38 for(j=1;j<=n;j++) 39 if(g[x][c[j]]==1)l[x]=2;else 40 if(g[x][c[j]]==-1)r[x]=2; 41 } 42 } 43 X=Find(A);Y=Find(B); 44 for(n=M,i=1;i<n;i++) 45 if(i!=A&&i!=B){ 46 x=Find(i); 47 for(j=i+1;j<=n;j++) 48 if(j!=A&&j!=B){ 49 memset(p,0,sizeof(p));y=Find(j); 50 for(a[1]=l[X];a[1]<=r[X];a[1]++) 51 for(a[2]=l[Y];a[2]<=r[Y];a[2]++) 52 for(a[3]=l[x];a[3]<=r[x];a[3]++) 53 for(a[4]=l[y];a[4]<=r[y];a[4]++){ 54 b[1]=X;b[2]=Y;b[3]=x;b[4]=y;Flag=0; 55 for(k1=1;k1<4;k1++) 56 for(k2=k1+1;k2<=4;k2++) 57 if(a[k1]!=a[k2]&&b[k1]==b[k2]){Flag=1;k1=4;break;}else 58 if(g[b[k1]][b[k2]]==1&&a[k1]<=a[k2]){Flag=1;k1=4;break;}else 59 if(g[b[k1]][b[k2]]==-1&&a[k1]>=a[k2]){Flag=1;k1=4;break;} 60 if(Flag)continue; 61 if(a[1]+a[2]>a[3]+a[4])p[0]=1;else 62 if(a[1]+a[2]==a[3]+a[4])p[1]=1;else p[2]=1; 63 } 64 if(p[0]+p[1]+p[2]==1)for(k1=0;k1<3;k1++)Ans[k1]+=p[k1]; 65 } 66 } 67 printf("%d %d %d\n",Ans[0],Ans[1],Ans[2]); 68 return 0; 69 }
以上是关于bzoj1077 -- 并查集的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ 1202 [HNOI2005]狡猾的商人(并查集)
bzoj2733 [ HNOI2012 ] -- 并查集+线段树合并
BZOJ4025 二分图 分治 并查集 二分图 并查集按秩合并 带权并查集