HDU 3234 Exclusive-OR 扩展并查集

这个题坑了我两小时,查了半天,最后发现自己一直都弄错了运算符的优先性。val[p]^val[q]!=v是错的,应该写成((val[p]^val[q])!=v),异或运算符优先性比关系运算符==低#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int root[20010],val[20010],temp[20],xor[20],roo[20]; int n,Q; int query(int x){ int tem; if(root[x]!=x){ tem=root[x]; root[x] = query(root[x]); val[x]=val[x]^val[tem]; } return root[x]; } void Union(int x,int y,int Val){ int tem1,tem2; tem1=query(x); tem2=query(y); if(tem1==n){ swap(tem1,tem2); } root[tem1]=tem2; val[tem1]=val[x]^val[y]^Val; } int main(){ int l,i,j,k,p,q,v,flag,fa1,fa2,sign,cas,boo,fact; int num,in,tem,all,ans; char a[10240],str[10240]; cas=0; while(scanf("%d %d",&n,&Q)==2 && !(n==0 && Q==0)){ fact=0; printf("Case %d:\n",++cas); for(i=0;i<=n;i++) root[i]=i; memset(val,0,sizeof(val)); flag=0; for(l=1;l<=Q;l++){ scanf("%s",a); if(flag){gets(str);continue;} if(a[0]=='I'){ fact++; gets(str); int t=sscanf(str,"%d%d%d",&p,&q,&v); if(t==2){ swap(q,v); q=n; } fa1=query(p); fa2=query(q); if(fa1==fa2){ if((val[p]^val[q])!=v) if(!flag){ flag=1; printf("The first %d facts are conflicting.\n", fact); } } else if(fa1!=fa2){ Union(p,q,v); } } else{ scanf("%d",&num); all=0; memset(xor,0,sizeof(xor)); memset(roo,0,sizeof(roo)); memset(temp,0,sizeof(temp)); for(j=1;j<=num;j++){ scanf("%d",&in); tem=query(in); if(j!=1){ for(k=1;k<=all;k++){ if(roo[k]==tem) break; } } if(j==1 || k==all+1){ temp[++all]=1; roo[all]=tem; xor[all]=val[in]; } else{ temp[k]++; xor[k]^=val[in]; } } ans=0; if(flag) continue; sign=0; for(i=1;i<=all;i++){ if(temp[i]%2==1 && roo[i]!=n){ printf("I don't know.\n"); sign=1; break; } ans^=xor[i]; } if(!sign) printf("%d\n",ans); } } puts(""); } return 0; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值