题解:

2-sat

对于bob出的每一张牌,alice显然只有两种选择

然后对于每一个限制,连边

判断是否可行

代码:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=200005;
int flag[N],ans,T,cas,m,x,y,kkk,k,l,n;
int ne[N],fi[N],a[N],b[N],zz[N],num,t,zhan[N],dfn[N],low[N],an[N];
void init()
{
    printf("Case #%d: ",++cas);
    kkk=1;num=l=0;
    memset(fi,0,sizeof fi);
    memset(an,0,sizeof an);
    memset(dfn,0,sizeof dfn);
}
void jb(int x,int y)
{
    ne[++num]=fi[x];
    fi[x]=num;
    zz[num]=y;
}
void dfs(int x)
{
    low[x]=dfn[x]=++l;
    zhan[++t]=x;
    flag[x]=true;
    for (int i=fi[x];i!=0;i=ne[i])
     {
         if (an[zz[i]])continue;
        if(!dfn[zz[i]])dfs(zz[i]);
        if(!flag[zz[i]])low[x]=min(low[x],dfn[zz[i]]);else
        low[x]=min(low[x],low[zz[i]]);
     }
    if (dfn[x]==low[x])
     {
         ans++;
         while (zhan[t]!=x)
          {
              flag[zhan[t]]=false;
              an[zhan[t--]]=ans;
          }
         an[zhan[t--]]=ans;
         flag[x]=false;
     }
}
int main()
{
    scanf("%d",&T);
    while (T--)
     {
         init();
         scanf("%d%d",&n,&m);
         for (int i=0;i<n;i++)
          {
              scanf("%d",&x);x--;
              a[i]=x;a[i+n]=(x+1)%3;
          }
         while (m--)
         {
             scanf("%d%d%d",&x,&y,&k);
             x--;y--;
             if (k==0)
              {
                 if (a[x]!=a[y+n])jb(x,y),jb(y+n,x+n);
                  if (a[x]!=a[y])jb(x,y+n),jb(y,x+n);
                  if (a[x+n]!=a[y+n])jb(x+n,y),jb(y+n,x);
                  if (a[x+n]!=a[y])jb(x+n,y+n),jb(y,x);
              }
             else
             {
                 if (a[x]==a[y+n])jb(x,y),jb(y+n,x+n);
                  if (a[x]==a[y])jb(x,y+n),jb(y,x+n);
                  if (a[x+n]==a[y+n])jb(x+n,y),jb(y+n,x);
                  if (a[x+n]==a[y])jb(x+n,y+n),jb(y,x);
             } 
         }
        for (int i=0;i<2*n;i++)
         if (!dfn[i])dfs(i);
        for (int i=0;i<n;i++)
         if (an[i]==an[i+n])
          {
              puts("no");
              kkk=0;
              break;
          }  
        if (kkk)puts("yes"); 
     }
}

 

posted on 2017-12-27 19:00  宣毅鸣  阅读(101)  评论(0编辑  收藏  举报