您的位置:首页 > 其它

hdu 3234 并查集

2013-09-01 10:34 190 查看
虚拟一个根节点n,设其值为0.并且始终保持其为根。

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<cstdio>
#include<vector>
#include<string>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define Maxn 40010
#define Maxm 100010
#define LL __int64
#define Abs(x) ((x)>0?(x):(-x))
#define lson(x) (x<<1)
#define rson(x) (x<<1|1)
#define inf 0x7fffffff
#define Mod 1000000007
using namespace std;
int fa[Maxn],val[Maxn],n;
map<int,int> num;
void init()
{
for(int i=0;i<Maxn;i++){
fa[i]=i;
val[i]=0;
}
}
int find(int x)
{
if(fa[x] == x)
return x;
int t = find(fa[x]);
val[x] ^= val[fa[x]];
fa[x] = t;
return t;
}
int merg(int a,int b,int v)
{
int x=find(a);
int y=find(b);
if(x==y){
return (val[a]^val[b])==v;
} //cout<<x<<" * "<<y<<endl;
if(x==n){
fa[y]=x;
val[y]=val[a]^val[b]^v;
return 1;
}
if(y==n){
fa[x]=y;
val[x]=val[a]^val[b]^v;
return 1;
}
fa[x]=y;
val[x]=val[a]^val[b]^v;
return 1;
}
int main()
{
int q,i,j,x,y,v,cnt=0,k,ans,ok,Case=0;
char str[20],ch[5];
while(scanf("%d%d",&n,&q)!=EOF,n||q){
init();
int err=0;
cnt=0;
printf("Case %d:\n",++Case);
for(i=1;i<=q;i++){
scanf("%s",ch);
if(ch[0]=='I'){
gets(str);
if(err) continue;
++cnt;
if(sscanf(str,"%d %d %d",&x,&y,&v)==2){
v=y;
y=n;
//cout<<x<<" "<<y<<" "<<v<<endl;
if(!merg(x,y,v)){
err=1,printf("The first %d facts are conflicting.\n",cnt);
}
}
else {
//cout<<x<<" "<<y<<" "<<v<<endl;
if(!merg(x,y,v)){
err=1,printf("The first %d facts are conflicting.\n",cnt);
}
}
}
else {
scanf("%d",&k);
ans=0;
ok=0;
num.clear();
for(j=1;j<=k;j++){
scanf("%d",&x);
if(err) continue;
int t=find(x);
ans^=val[x];
//cout<<t<<" "<<x<<" "<<find(0)<<endl;
if(t!=n){
if(num[t]%2==0){
ok++;
num[t]++;
}else ok--,num[t]--;
}
}
if(err) continue;
if(!ok){
printf("%d\n",ans);
}else{
printf("I don't know.\n");
}
}
}
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: