详细题解网上有好多。。
一开始想用一个并查集维护 确定关系
一个并查集维护相等关系
但会出现一些无解判不出来(原因未知)
所以就只能写加权并查集,记录每个点和他根节点的相等关系:0相等 1不等
然后原点选0还是1影响方块 1 0
已填的数影响方块 1 0
坐标影响 方块 1 0
统一一下就可以了
注:
1、分清变量!!!
2、分清变量!!!
3、分清变量!!!
AC 代码:
#include<iostream>
#include<cstdio>
using namespace std;
#define P 1000000000
int fu[2000005],g[2000005],ans,n,m,k,i,j,a[2000005],b[2000005],c[2000005];
bool sy[3];
int find(int o)
{
if(fu[o]==o)return o;
int t=find(fu[o]);
g[o]^=g[fu[o]];
return fu[o]=t;
}
int calc()
{
for(i=1;i<=n+m;i++)fu[i]=i,g[i]=0;
fu[n+1]=1;
for(i=1;i<=k;i++)
{
int lx=find(a[i]),ly=find(b[i]);
int lin=g[a[i]]^g[b[i]]^c[i];
// cout<<endl<<a[i]<<" "<<b[i]-n<<" "<<c[i]<<endl;
if(lx!=ly)
fu[lx]=ly,g[lx]=lin;
else
{
if(lin)return 0;
}
}
int daan=-1;
for(i=1;i<=n+m;i++)
{
if(i==find(i))
if(daan==-1)daan=1;
else{
daan*=2;
if(daan>=P)daan-=P;
}
}
return daan;
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
sy[0]=sy[1]=1;
for(i=1;i<=k;i++)
{
scanf("%d%d%d",&a[i],&b[i],&c[i]);
if(a[i]==1&&b[i]==1){sy[c[i]]=0,i--,k--;continue;}
if((a[i]&1)==0&&(b[i]&1)==0)c[i]^=1;
b[i]+=n;
}
if(sy[1])ans=calc();
//cout<<ans<<" ";
if(sy[0])
{
for(i=1;i<=k;i++)
{
if (a[i]>1 && b[i]>n+1) c[i]^=1;
}
ans+=calc();
}
printf("%d",ans%P);
}
90分莫名wa代码:
#include<iostream>
#include<cstdio>
using namespace std;
#define P 1000000000
#define ll long long
int n,m,i,fu[2000006],fu2[2000006],cnt,a[2000006],b[2000006],c[2000006],k,j,bt[2000006];
bool cx[2000006];
ll ans;
ll ksm(ll a,ll b)
{
ll ans=1;
while(b)
{
if(b%2)ans=(ans*a)%P;
b/=2;
a=(a*a)%P;
}
return ans;
}
int find(int o)
{
if(fu[o]!=o)fu[o]=find(fu[o]);
return fu[o];
}
int find2(int o)
{
if(fu2[o]!=o)fu2[o]=find2(fu2[o]);
return fu2[o];
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
if(n==1||m==1)
{
printf("0");
return 0;
}
for(i=1;i<=n+m;i++)fu[i]=fu2[i]=i;//fu
fu2[1]=fu2[1+n];
fu[1]=fu[1+n];
int lin=-1;
for(i=1;i<=k;i++)
{
scanf("%d%d%d",&a[i],&b[i],&c[i]);
if(lin==-1)
{if(a[i]==1&&b[i]==1)lin=c[i];}
else if(a[i]==1&&b[i]==1)
{
printf("0");
return 0;
}
b[i]+=n;
}
//1,1为 0
if(lin!=1){for(i=1;i<=k;i++)
{ fu2[find2(a[i])]=fu2[find2(b[i])];
if(a[i]==1||b[i]==n+1)
{
if(c[i]==0)
{
fu[find(a[i])]=fu[find(b[i])];
}else
{
if(bt[a[i]]>0)
{
fu[find(bt[a[i]])]=find(b[i]);
}else bt[a[i]]=b[i];
if(bt[b[i]]>0)
{
fu[find(bt[b[i]])]=find(a[i]);
}else bt[b[i]]=a[i];
}
}else
if((a[i]&1)==0&&((b[i]-n)&1)==0)//^=1
{
if(c[i]==1)
{
fu[find(a[i])]=fu[find(b[i])];
}else
{
if(bt[a[i]]>0)
{
fu[find(bt[a[i]])]=find(b[i]);
}else bt[a[i]]=b[i];
if(bt[b[i]]>0)
{
fu[find(bt[b[i]])]=find(a[i]);
}else bt[b[i]]=a[i];
}
}
else
{
if(c[i]==0)
{
fu[find(a[i])]=fu[find(b[i])];
}else
{
if(bt[a[i]]>0)
{
fu[find(bt[a[i]])]=find(b[i]);
}else bt[a[i]]=b[i];
if(bt[b[i]]>0)
{
fu[find(bt[b[i]])]=find(a[i]);
}else bt[b[i]]=a[i];
}
}
}
bool ky=1;
for(i=1;i<=n+m;i++)
{cx[i]=0;
if(find(i)==find(bt[i]))
{
ky=0;break;
}
}
cnt=-1;
for(i=1;i<=n+m;i++)
{
if(cx[find2(i)]==0)
{
cnt++;
cx[find2(i)]=1;
}
}
if(ky==1)ans=ksm(2,cnt);
}
// cout<<cnt<<" "<<ans<<" ";
for(i=1;i<=n+m;i++)fu[i]=fu2[i]=i,bt[i]=0;
fu2[1]=fu2[1+n];
fu[1]=fu[n+1];
//1,1为 1
if(lin!=0)
{for(i=1;i<=k;i++)
{ fu2[find2(a[i])]=fu2[find2(b[i])];
if(a[i]==1||b[i]==n+1)
{
if(c[i]==1)
{
fu[find(a[i])]=fu[find(b[i])];
}else
{
if(bt[a[i]]>0)
{
fu[find(bt[a[i]])]=find(b[i]);
}else bt[a[i]]=b[i];
if(bt[b[i]]>0)
{
fu[find(bt[b[i]])]=find(a[i]);
}else bt[b[i]]=a[i];
}
}else
if((a[i]&1)==0&&((b[i]-n)&1)==0)//^=1
{
if(c[i]==0)
{
fu[find(a[i])]=fu[find(b[i])];
}else
{
if(bt[a[i]]>0)
{
fu[find(bt[a[i]])]=find(b[i]);
}else bt[a[i]]=b[i];
if(bt[b[i]]>0)
{
fu[find(bt[b[i]])]=find(a[i]);
}else bt[b[i]]=a[i];
}
}
else
{
if(c[i]==1)
{
fu[find(a[i])]=fu[find(b[i])];
}else
{
if(bt[a[i]]>0)
{
fu[find(bt[a[i]])]=find(b[i]);
}else bt[a[i]]=b[i];
if(bt[b[i]]>0)
{
fu[find(bt[b[i]])]=find(a[i]);
}else bt[b[i]]=a[i];
}
}
}
bool ky=1;
for(i=1;i<=n+m;i++)
{cx[i]=0;
if(find(i)==find(bt[i]))
{
ky=0;break;
}
}
cnt=-1;
for(i=1;i<=n+m;i++)
{
if(cx[find2(i)]==0)
{
cnt++;
cx[find2(i)]=1;
}
}
if(ky==1)ans+=ksm(2,cnt),ans%=P;
}
printf("%lld",ans);
}