您的位置:首页 > 其它

UVA 12232 Exclusive-OR (带权值的并查集)

2016-11-04 21:54 381 查看
I don‘t know直接复制网站上的话一直WA,直接复制’是错的。

复杂的并查集问题,一般都需要和父节点联系。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
const int maxn=40000+5;
int pa[maxn],w[maxn];
int n,m,conflict;
int findset(int x)
{
if(pa[x]==x) return x;
int root=findset(pa[x]);
w[x]^=w[pa[x]];
return pa[x]=root;
}
void merge(int p,int q,int v)
{
int x=findset(p),y=findset(q);
if(x==y){
if((w[p]^w[q])!=v) conflict=1;
return ;
}
if(x==n) swap(x,y);
pa[x]=y;
w[x]=w[p]^w[q]^v;
}
char cmd[20];
int main()
{
int kase=0;
while(scanf("%d%d",&n,&m)&&(n+m))
{
printf("Case %d:\n",++kase);
for(int i=0;i<=n;i++) pa[i]=i;
memset(w,0,sizeof(w));
int k=0;
conflict=0;
while(m--)
{
int p,q,v;
scanf("%s",cmd);
if(cmd[0]=='I'){
k++;
gets(cmd);
if(conflict) continue;
if(sscanf(cmd,"%d%d%d",&p,&q,&v)==2){v=q;q=n;}
merge(p,q,v);
if(conflict) printf("The first %d facts are conflicting.\n",k);
}
else{
int K,t,ans=0,know=1;
map<int,int> M;
map<int,int>::iterator it;
scanf("%d",&K);
while(K--)
{
scanf("%d",&t);
int x=findset(t);
ans^=w[t];
M[x]++;
}
if(conflict) continue;
for(it=M.begin();it!=M.end();it++){
if(it->second%2==1){
if(it->first!=n) {know=0;break;}
}
}
if(know) printf("%d\n",ans);
else printf("I don't know.\n");
}
}
puts("");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: