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

 

以上是关于bzoj1077 -- 并查集的主要内容,如果未能解决你的问题,请参考以下文章

bzoj4668: 冷战 并查集按秩合并

BZOJ 1202 [HNOI2005]狡猾的商人(并查集)

bzoj2733 [ HNOI2012 ] -- 并查集+线段树合并

BZOJ4025 二分图 分治 并查集 二分图 并查集按秩合并 带权并查集

BZOJ 1196 [HNOI2006]公路修建问题(二分答案+并查集)

[BZOJ 3673]可持久化并查集 by zky