hdu3234 Exclusive-OR 带权并查集
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu3234 Exclusive-OR 带权并查集相关的知识,希望对你有一定的参考价值。
不想再调这道题了。。。这题我早就会了,但是读入实在是坑。。。。就是坑。。。。没错,这次真的是坑。。。。。。
不能在坑题上浪费太多时间,既没有明显提高代码能力,又不能提高思维,也不能学到知识点。
我只能说,出题人心理为何如此阴暗,出这样的题和报复社会有什么区别。。。
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<vector> #define REP(i,a,b) for(int i=a;i<=b;i++) #define MS0(a) memset(a,0,sizeof(a)) using namespace std; typedef long long ll; const int maxn=1000100; const int INF=1e9+10; int n,m; char op[10];int p,q,v; int k,pk[40]; vector<int> d[40];int dn; int fa[maxn],w[maxn],val[maxn]; int flag; int rk; int sz[maxn]; void Init() { REP(i,0,2) fa[i]=i,w[i]=0,val[i]=-1,sz[i]=1; REP(i,0,20) d[i].clear(); } int find(int x) { if(fa[x]==x) return x; int t=find(fa[x]); w[t]=0; w[x]^=w[fa[x]]; return fa[x]=t; } void Union(int p,int q,int v) { if(flag==0) return; int x=find(p),y=find(q); if(x==y){ if((w[p]^w[q])!=v) flag=0; } else{ if(sz[x]>sz[y]) swap(x,y),swap(p,q); if(~val[x]&&~val[y]){ if((w[p]^val[x]^w[q]^val[y])!=v) flag=0; else{ fa[x]=y; sz[y]+=sz[x]; sz[x]=0; w[x]=(w[p]^w[q]^v); w[y]=0; } } else{ fa[x]=y; w[x]=(w[p]^w[q]^v); w[y]=0; if(val[y]==-1){ if(~val[x]) val[y]=(val[x]^w[x]); } } } if(flag==0) printf("The first %d facts are conflicting.\n",rk); } void change(int p,int v) { if(flag==0) return; int x=find(p); if(~val[x]){ if((w[p]^val[x])!=v) flag=0; } else val[x]=(v^w[p]); if(flag==0) printf("The first %d facts are conflicting.\n",rk); } bool cmp(int a,int b) { return fa[a]<fa[b]; } int query() { REP(i,1,k) d[i].clear(); int res=0; sort(pk+1,pk+k+1,cmp); dn=1; d[1].push_back(pk[1]); int px=fa[pk[1]]; REP(i,2,k){ if(fa[pk[i]]==px) d[dn].push_back(pk[i]); else{ ++dn; px=fa[pk[i]]; d[dn].push_back(pk[i]); } } REP(i,1,dn){ if((int)d[i].size()%2==0){ for(int j=0;j<d[i].size();j++) res^=w[d[i][j]]; } else{ int x=fa[d[i][0]]; if(val[x]==-1) return -1; for(int j=0;j<d[i].size();j++) res^=(val[x]^w[d[i][j]]); } } return res; } void solve() { flag=1;rk=0; REP(i,1,m){ scanf("%s",op); if(op[0]==‘I‘){ ++rk; gets(op); if(sscanf(op,"%d%d%d",&p,&q,&v)==3) Union(p,q,v); else change(p,q); } else{ scanf("%d",&k); REP(i,1,k){ scanf("%d",&pk[i]); find(pk[i]); } if(flag==0) continue; ll tmp=query(); if(tmp==-1) printf("I don‘t know.\n"); else printf("%d\n",tmp); } } } int main() { freopen("in.txt","r",stdin); int casen=1; while(~scanf("%d%d",&n,&m)){ if(n==0&&m==0) break; printf("Case %d:\n",casen++); Init(); solve(); puts(""); } return 0; } /** 6 5 I 1 2 1 I 3 4 2 I 4 5 3 Q 2 3 5 Q 4 1 2 3 5 2 6 I 0 1 3 Q 1 0 Q 2 1 0 I 0 2 Q 1 1 Q 1 0 3 3 I 0 1 6 I 0 2 2 Q 2 1 2 2 4 I 0 1 7 Q 2 0 1 I 0 1 8 Q 2 0 1 0 0 */
以上是关于hdu3234 Exclusive-OR 带权并查集的主要内容,如果未能解决你的问题,请参考以下文章