55pts求调,悬赏一关注
查看原帖
55pts求调,悬赏一关注
663638
Butterfly_qwq楼主2022/12/27 11:21
#include<bits/stdc++.h>
using namespace std;
int n,m,k,x[114514],y[114514],c[114514],f[2],fa[200001],val[200001];
//f:是否进行 fa:带权并查集父亲 val:带权并查集权值
const int mod=1e9;//模数
int find(int x)
{
	if(x==fa[x])return x;
	val[x]^=val[fa[x]];
	return fa[x]=find(fa[x]);
}
int rma()
{
	for(int i=1;i<=n+m;i++)fa[i]=i;
	fa[n+1]=1;//差点被坑……n+1和1是一个点!!!!!!
	for(int i=1;i<=k;i++)
	{
		int fax=find(x[i]),fay=find(y[i]+n);//找出x和y的祖先
		if(fax!=fay)//合并
		{
			fa[fax]=fay;
			val[fax]=val[x[i]]^val[y[i]+n]^c[i];//这个脑瘫没有异或上c[i]调了半个小时
		}
		else if(val[x[i]]^val[y[i]+n]^c[i])return 0;//不要忘记矛盾情况虽然我没有忘记
	}
	int res=-114514;//统计答案
	for(int i=1;i<=n+m;i++)
	{
		if(fa[i]==i)
		{
			if(res==-114514)res=1;//记得减去(1,1)对应的连通块
			else
			{
				res*=2;
				res%=mod;
			}
		}
	}
	return res;
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int ans=0;
	cin>>n>>m>>k;
	f[0]=f[1]=1;
	for(int i=1;i<=k;i++)
	{
		cin>>x[i]>>y[i]>>c[i];
		if(x[i]==1&&y[i]==1)f[c[i]^1]=0;//标记是否进行
		if(x[i]%2==0&&y[i]%2==0)c[i]^=1;//为了以后方便处理
	}
	if(f[0])ans+=rma();
	if(f[1])
	{
		for(int i=1;i<=k;i++)
			if(x[i]!=1&&y[i]!=1)c[i]^=1;//异或1正好取反
		ans+=rma();
	}
	cout<<ans%mod;
	return 0;
}
2022/12/27 11:21
加载中...