Parity game 並查集+邊帶權/拓展域

LINK
轉化一下如果
s[l,r]中有偶數個1 那麼sum[r]中的1的奇偶性就和sum[l-1]的奇偶性相同了
傳遞:
x1 x2 奇偶性相同 x2 x3 相同 ->x1 x3同
x1 x2 奇偶性不同 x2 x3不同-> x1 x3 同

採用 邊帶權的並查集
d[x] =0 表示x與fa[x]的就相同 ;=1 表示不同

#include<bits/stdc++.h>
using namespace std;
const int N=20010;
struct node
{
	int l,r,ans;
}q[N];
int n,m,t;
int fa[N],a[N],d[N];
int find(int x)
{
	if(x==fa[x]) return x;
	int rt=find(fa[x]) ;
	d[x]^=d[fa[x]];
	return fa[x]=rt;
}
int main()
{
	int n,m;scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		char s[10];
		scanf("%d%d%s",&q[i].l,&q[i].r,s);
		q[i].ans=(s[0]=='o'?1:0);
		a[++t]=q[i].l -1;
		a[++t]=q[i].r ;
	}
	sort(a+1,a+1+t);
	n=unique(a+1,a+1+t)-a-1;
	for(int i=1;i<=n;i++) fa[i]=i;
	for(int i=1;i<=m;i++)
	{
		int x=lower_bound(a+1,a+1+n,q[i].l-1)-a;
		int y=lower_bound(a+1,a+1+n,q[i].r )-a;
		int xx=find(x),yy=find(y);
		if(xx==yy)
		{
			if(d[x]^d[y]!=q[i].ans )//矛盾輸出
			{
				printf("%d\n",i-1);return 0;
			}
		}else 
		{
			fa[yy]=xx;//合併
			d[yy]=d[x]^d[y]^q[i].ans;
		}
	}
	printf("%d\n",m);
} 
  • 拓展域 x表示爲偶數的情況 x+n表示爲奇數的情況
    對於 ans =0
    x=l-1 y=r 可以得到
    sum[x] 爲偶數 sum[y]爲偶數
    或者sum[x]爲奇數 sum[y]爲奇數
    對於 ans=1
    x=l-1y=r 可以得到
    sum[x]爲偶數 sum[y]爲奇數
    或者sum[x]爲奇數 sum[y]爲偶數
#include<bits/stdc++.h>
using namespace std;
int fa[10001],a[10001];
struct node
{
	int l,r,o;
}q[5001];
int find(int x)
{
	if(fa[x]==x) return x;
	return fa[x]=find(fa[x]);
}
int main()
{
	int n,m,t=0;scanf("%d%d",&n,&m);
	for(int i=1;i<=10000;i++) fa[i]=i;
	for(int i=1;i<=m;i++)
	{
		char s[10];
		scanf("%d%d%s",&q[i].l,&q[i].r,s);
		q[i].o=s[0]=='o'?1:0;
		a[++t]=q[i].l-1;
		a[++t]=q[i].r; 
	}
	sort(a+1,a+1+t);
	n=unique(a+1,a+1+t)-a-1;
	for(int i=1;i<=m;i++)
	{
		int x=lower_bound(a+1,a+1+n,q[i].l-1)-a;
		int y=lower_bound(a+1,a+1+n,q[i].r)-a;
		if(q[i].o==0)//奇偶性一致
		{
			if(find(x)==find(y+n)) 
			{
				printf("%d\n",i-1);
				return 0;
			}
            fa[find(x)]=find(y);
            fa[find(x+n)]=find(y+n);
		}else //奇偶性不一致
		{
			if(find(x)==find(y))
			{
				printf("%d\n",i-1);
				return 0;
			}
			fa[find(x+n)]=find(y);
			fa[find(x)]=find(y+n);
		}
	}
	printf("%d\n",m);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章