题解:
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"); } }