2017.10.22 方格染色 失败总结

来源:互联网 发布:2016安全软件排名 编辑:程序博客网 时间:2024/05/18 02:21

详细题解网上有好多。。

一开始想用一个并查集维护  确定关系

一个并查集维护相等关系

但会出现一些无解判不出来(原因未知)

所以就只能写加权并查集,记录每个点和他根节点的相等关系:0相等 1不等

然后原点选0还是1影响方块 1 0

已填的数影响方块 1 0

坐标影响 方块 1 0

统一一下就可以了


注:

1、分清变量!!!

2、分清变量!!!

3、分清变量!!!



AC 代码:

#include<iostream>#include<cstdio>using namespace std;#define P 1000000000int 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 longint 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);}


原创粉丝点击