</pre><pre name="code" class="cpp">#include<cstring>
#include<cstdio>
#include<iostream>
#include<climits>
#include<cmath>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#define INF 0x3f3f3f3f
#define MAXN 20010
#define MAXM 3010
using namespace std;
int N,Q,bug,p[MAXN],w[MAXN];
char str[20];
int find(int x){
if(p[x]==x) return x;
int root=find(p[x]);
w[x]^=w[p[x]];///更新到最新根节点root的距离
return p[x]=root;
}
void Union(int a,int b,int v){
int x=find(a),y=find(b);
if(x==y){
if((w[a]^w[b])!=v) bug=1; //这里如果不打括号就是错的
return;
}
if(x==N) swap(x,y); //N要始终作为根节点
p[x]=y;//x根节点为y
w[x]=w[a]^w[b]^v;///x到y距离为 x到a距离^a到b^b到y
}
int main(){
// freopen("in.txt","r",stdin);
int cas=0;
while(scanf("%d%d",&N,&Q),N||Q){
printf("Case %d:\n",++cas);
for(int i=0;i<=N;i++) p[i]=i;///加一个新节点N w[N]=0
memset(w,0,sizeof(w));
int k=0;
bug=0;
while(Q--){
int a,b,v;
scanf("%s",str);
if(str[0]=='I'){
k++;
gets(str);
if(bug) continue;
if(sscanf(str,"%d%d%d",&a,&b,&v)==2){
v=b;
b=N;
}
Union(a,b,v);
if(bug) printf("The first %d facts are conflicting.\n",k);
}
else{
int K,t,ans=0,know=1;
map<int,int> Map;
map<int,int>::iterator it;
scanf("%d",&K);
while(K--){
scanf("%d",&t);
int x=find(t);
ans^=w[t];
Map[x]++;
}
if(bug) continue;
for(it=Map.begin();it!=Map.end();it++) if(it->second%2){///如果 根节点个数不是偶数(不能抵消)
if(it->first!=N){///如果不是N那么无法得到答案
know=0;
break;
}
}
if(know) printf("%d\n",ans);
else printf("I don't know.\n");
}
}
puts("");
}
return 0;
}
UVA12232加权并查集 加点
最新推荐文章于 2016-12-09 20:46:37 发布