奇偶游戏
本题图片以及题解来自Bug-Free 题解网址:https://www.acwing.com/solution/content/29308/   
带权并查集
#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_map>
using namespace std;
const int N = 10010;
int n=0,m;
int p[N],d[N];
unordered_map<int,int>S;
int get(int x)
{
if(!S.count(x))
{
S[x]=++n;
}
return S[x];
}
int find(int x)
{
if(p[x]!=x)
{
int root=find(p[x]);
d[x]^=d[p[x]];
p[x]=root;
}
return p[x];
}
int main()
{
cin>>n>>m;
n=0;
int res=m;
for(int i=0;i<N;i++)p[i]=i;
for(int i=1;i<=m;i++)
{
int a,b;
string s;
cin>>a>>b>>s;
a=get(a-1),b=get(b);
int t=0;
if(s=="odd")t=1;
int pa=find(a),pb=find(b);
if(pa==pb)
{
if((d[a]^d[b])!=t)
{
res=i-1;
break;
}
}
else
{
p[pa]=pb;
d[pa]=d[a]^d[b]^t;
}
}
cout<<res<<endl;
}

扩展域并查集
#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_map>
using namespace std;
const int N = 10010,base=N/2;
int n,m;
int p[N],d[N];
unordered_map<int,int>S;
int get(int x)
{
if(!S.count(x))
{
S[x]=++n;
}
return S[x];
}
int find(int x)
{
if(p[x]!=x)p[x]=find(p[x]);
return p[x];
}
int main()
{
cin>>n>>m;
n=0;
int res=m;
for(int i=0;i<N;i++)p[i]=i;
for(int i=1;i<=m;i++)
{
int a,b;
string s;
cin>>a>>b>>s;
a=get(a-1),b=get(b);
if(s=="even")
{
if(find(a+base)==find(b))
{
res=i-1;
break;
}
p[find(a)]=find(b);
p[find(a+base)]=find(b+base);
}
else
{
if(find(a)==find(b))
{
res=i-1;
break;
}
p[find(a+base)]=find(b);
p[find(a)]=find(b+base);
}
}
cout<<res<<endl;
}
|