80pts求助,带权并查集,能给个hack也好啊QAQ
查看原帖
80pts求助,带权并查集,能给个hack也好啊QAQ
244597
kabout楼主2023/6/18 01:22
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define mm(a,b) memset(a,b,sizeof(a))
#define pf push_front
#define pb push_back
#define M 1000000000
#define TLE ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define N 100010
ll n,m,k,fa[2*N],x[N],y[N],xy[N],val[N],alr[2*N],ans;
map<int,int>mp;
deque<int>que;
int Find(int u)
{
	if(u==fa[u])return u;
	int tmp=fa[u];
	fa[u]=Find(fa[u]);
	val[u]^=val[tmp];
	return fa[u];
}
bool mer(int u,int v,int t)
{
	int fx=Find(u),fy=Find(v);
	if(fx!=fy){//没有合并
		val[fx]=t^val[u]^val[v];
		fa[fx]=fy;		
	}
	Find(u),Find(v);
	if(val[u]^val[v]!=t)return 0;//有冲突了
	return 1;
}
int main()
{
 	TLE;
 	cin>>n>>m>>k;
 	for(int i=1;i<=k;i++)cin>>x[i]>>y[i]>>xy[i];
 	for(int i=0;i<2;i++)
 	{
 		bool f=1;
	 	mm(alr,-1);
	 	mm(val,0);
 		mp.clear();
 		while(que.size())que.pop_front();
 		for(int j=1;j<=n+m;j++)fa[j]=j;//首先遍历
 		for(int j=1;j<=k;j++)
 		{
 			if(x[j]==1&&y[j]==1&&xy[j]!=i){f=0;break;}//直接冲突
			else if(x[j]==1&&y[j]!=1)alr[n+y[j]]=xy[j];
			else if(y[j]==1&&x[j]!=1)alr[x[j]]=xy[j];//这些是可以直接赋值的
			else
			{
	 			int tt=i^xy[j]^(!((x[j]%2)||(y[j]%2)));//当前有东西的
	 			if(mer(x[j],y[j]+n,tt)==0){//这是合并冲突
	 				f=0;
	 				break;
				}				
			}		
		}
		if(f)
		{
			for(int j=2;j<=n+m;j++)//注意的是第一个不能有	
			{
				if(j==n+1)continue;
				if(mp[Find(j)]==0)mp[Find(j)]=1,que.pb(Find(j));
				if(alr[j]!=-1)//代表已经有了
				{
					if(alr[Find(j)]==-1)alr[Find(j)]=val[j]^alr[j];
					else if(alr[Find(j)]!=val[j]^alr[j])alr[Find(j)]=2;//这些就G
				}
			}	
			ll ant=1;
			while(que.size())
			{
				int tm=que.front();
				que.pop_front();
				if(alr[tm]==-1)ant=ant*2%M;
				else if(alr[tm]==2){ant=0;break;}
			}
			ans+=ant;	
		}
	}
	cout<<ans%M<<endl;
 	return 0;
}

2023/6/18 01:22
加载中...