POJ 1733 Parity game(加权并查集)
题意:这是一个01的串,然后有m个类似于询问的东西,每次询问都告诉你这个区间的和为奇数还是偶数,让你判断正确的有几句,如果不正确,直接跳出
思路:和华中科技大学的决赛差不多,我们将奇数设为1,偶数为0,那我们可以发现他们的奇偶性可以用异或代替,然后就穿一样了,加上判断条件就OK了,记得离散化
代码:
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> using namespace std; typedef long long LL; inline LL read() { LL x=0,f=1;char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } const int maxn=2e4+7; struct node { int x,y,w; }q[maxn]; int fa[maxn]; int sum[maxn]; int sa[maxn]; int len; int Find(int x) { if(x!=fa[x]){ int t=fa[x]; fa[x]=Find(fa[x]); sum[x]^=sum[t]; } return fa[x]; } int main() { int n,m; while(~scanf("%d%d",&n,&m)){ len=0; int ans=0; bool ok=false; char op[15]; for(int i=1;i<=m;i++){ int a,b,w; scanf("%d%d%s",&a,&b,op); if(op[0]=='e')w=0; else w=1; a--; q[i].x=a;q[i].y=b;q[i].w=w; sa[++len]=a; sa[++len]=b; } sort(sa+1,sa+1+len); len=unique(sa+1,sa+1+len)-sa-1; for(int i=0;i<=len;i++){ fa[i]=i; sum[i]=0; } for(int i=1;i<=m;i++){ int a=lower_bound(sa+1,sa+len+1,q[i].x)-sa; int b=lower_bound(sa+1,sa+len+1,q[i].y)-sa; int rta=Find(a); int rtb=Find(b); if(rta==rtb){ if(sum[a]==sum[b]&&q[i].w==1)break; if(sum[a]!=sum[b]&&q[i].w==0)break; ans++; } else{ fa[rta]=rtb; sum[rta]=sum[a]^sum[b]^q[i].w; ans++; } } printf("%d\n",ans); } return 0; } /* 10 5 1 2 even 3 4 odd 5 6 even 1 6 even 7 10 odd */