Parity game poj1733
阿新 • • 發佈:2018-11-02
有一個長度已知的01串,給出[l,r]這個區間中的1是奇數個還是偶數個,給出一系列語句問前幾個是正確的
解法一:帶權並查集。
#include<iostream> #include<algorithm> #define f(i,l,r) for(i=(l);i<=(r);i++) using namespace std; const int MAXN=5005; int fa[MAXN<<1],d[MAXN<<1]; int m,n,L; string s; struct Node{ int l,r,ans; }q[MAXN]; int h[MAXN<<1]; inline void Makeset() { int i; f(i,1,L){ fa[i]=i; } } inline int Find(int x) { if(fa[x]==x) return fa[x]; int root=Find(fa[x]); d[x]^=d[fa[x]]; return fa[x]=root; } int main() { ios::sync_with_stdio(false); int i,j; cin>>m>>n; f(i,1,n){ cin>>q[i].l>>q[i].r>>s; if(s=="even") q[i].ans=0; else q[i].ans=1; h[i+i-1]=q[i].l-1; h[i+i]=q[i].r; } sort(h+1,h+1+i+i); L=unique(h+1,h+1+i+i)-(h+1); Makeset(); f(i,1,n){ int x=lower_bound(h+1,h+1+L,q[i].l-1)-h; int y=lower_bound(h+1,h+1+L,q[i].r)-h; int fx=Find(x),fy=Find(y); if(fx==fy){ if(q[i].ans!=(d[x]^d[y])){ cout<<i-1<<endl; return 0; } } else{ fa[fx]=fy; d[fx]=d[x]^d[y]^q[i].ans; } } cout<<n<<endl; return 0; }
解法二:擴充套件域並查集。
#include<iostream> #include<algorithm> #define f(i,l,r) for(i=(l);i<=(r);i++) using namespace std; const int MAXN=10005; struct Node{ int l,r,ans; }q[MAXN]; int fa[MAXN<<1],h[MAXN]; int L,n,m; string s; inline void Makeset() { int i; f(i,1,L+L){ fa[i]=i; } } inline int Find(int x) { return fa[x]==x?x:fa[x]=Find(fa[x]); } inline void Union(int x,int y) { x=Find(x);y=Find(y); fa[x]=y; } int main() { ios::sync_with_stdio(false); int i,j; cin>>m>>n; f(i,1,n){ cin>>q[i].l>>q[i].r>>s; if(s=="even") q[i].ans=0; else q[i].ans=1; h[i+i-1]=q[i].l-1; h[i+i]=q[i].r; } sort(h+1,h+1+i+i); L=unique(h+1,h+1+i+i)-(h+1); Makeset(); f(i,1,n){ int x=lower_bound(h+1,h+1+L,q[i].l-1)-h; int y=lower_bound(h+1,h+1+L,q[i].r)-h; if(q[i].ans==0){ if(Find(x)==Find(y+L)){ cout<<i-1<<endl; return 0; } Union(x,y); Union(x+L,y+L); } else{ if(Find(x)==Find(y)){ cout<<i-1<<endl; return 0; } Union(x+L,y); Union(x,y+L); } } cout<<n<<endl; return 0; }