[(http://www.lydsy.com/JudgeOnline/problem.php?id=1823)]
比较简单的2-SAT QwQ
0 1分别表示用汉式还是满式 根据评委条件连边就行了
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int MaxN=205;
const int MaxM=100005;
int K,N,M,Cnt,EdgeCnt;
int A[1005],B[1005];
int Tot,Head[MaxN],Next[MaxM],To[MaxM];
int Index,DFN[MaxN],Low[MaxN];
int Top,Stack[MaxN],ID[MaxN];
bool Vis[MaxN];
struct Edge{
int u,v;
}E[MaxM];
void Add_Edge(int u,int v){
E[++EdgeCnt]=(Edge){u,v};
Next[++Tot]=Head[u];
To[Tot]=v;
Head[u]=Tot;
}
int Another(int x){
return (x%2?x+1:x-1);
}
void Init(){
int i,j,a,b;
char c1,c2;
scanf("%d%d",&N,&M);
for(i=1;i<=M;i++){
scanf("\n%c%d %c%d",&c1,&a,&c2,&b);
A[i]=a*2-(c1=='h');
B[i]=b*2-(c2=='h');
}
Tot=EdgeCnt=Cnt=0;
memset(Head,0,sizeof(Head));
for(i=1;i<=N*2;i++)
for(j=1;j<=M;j++){
if(A[j]==Another(i))
Add_Edge(i,B[j]);
if(B[j]==Another(i))
Add_Edge(i,A[j]);
}
}
void DFS(int u){
int i,v,tmp;
DFN[u]=Low[u]=++Index;
Vis[Stack[++Top]=u]=true;
for(i=Head[u];i;i=Next[i])
if(!DFN[v=To[i]]){
DFS(v);
Low[u]=min(Low[u],Low[v]);
}
else if(Vis[v])
Low[u]=min(Low[u],DFN[v]);
if(DFN[u]==Low[u]){
Cnt++;
do{
tmp=Stack[Top--];
ID[tmp]=Cnt;
Vis[tmp]=false;
}while(tmp!=u);
}
}
void Work(){
int i;
Index=Top=0;
memset(DFN,0,sizeof(DFN));
memset(Low,0,sizeof(Low));
for(i=1;i<=N*2;i++)
if(!DFN[i])
DFS(i);
for(i=1;i<=N*2;i+=2)
if(ID[i]==ID[i+1]){
puts("BAD");
return;
}
puts("GOOD");
}
int main(){
scanf("%d",&K);
while(K--){
Init();
Work();
}
return 0;
}