题解:

2-sat

对于每一个评委连边

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=10005;
char s1[10],s2[10];
int flag[N],n,pd,ne[N],fi[N],T,zz[N],num,t;
int zhan[N],dfn[N],m,l,q,ans,low[N],an[N];
int get(char s[])
{
    int k=0,l=0;
    for (int i=1;s[i];i++)k=k*10+s[i]-48;
    return s[0]=='m'?k-1:k+n-1;
}
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;
     }
}
void init()
{
    ans=num=l=pd=0;
    memset(fi,0,sizeof fi);
    memset(an,0,sizeof an);
    memset(dfn,0,sizeof dfn);
}
int main()
{
    scanf("%d",&T);
    while (T--)
     {
         init();
         scanf("%d%d",&n,&m);
         while (m--)
          {
              scanf("%s%s",s1,s2);
              int x=get(s1),y=get(s2);
              jb((x+n)%(2*n),y);jb((y+n)%(2*n),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])pd=1;
        if (pd)puts("BAD");
        else puts("GOOD"); 
     }
}

 

posted on 2018-01-01 12:13  宣毅鸣  阅读(93)  评论(0编辑  收藏  举报