BZOJ1823
来自蒟蒻XXJ的做题记录
2-SAT裸题啊QAQ
#include<bits/stdc++.h>
#define mem(i,j) memset(i,j,sizeof(i))
#define GO(i,here) for(int i=head[here];i!=-1;i=nex[i])
using namespace std;
const int MAXN=410;//最多是410个点
const int MAXM=1010*10;
//m: 1-n fm: 2n+1-3n h:n+1-2n fh:3n+1-4n
int n,m;
int head[MAXM],nex[MAXM],to[MAXM],top1;
int dfn[MAXN],low[MAXN],rk[MAXN],sum,tot;
int st[MAXN],top;
bool instack[MAXN],judge;
void add(int a,int b){
nex[top1]=head[a];head[a]=top1;to[top1++]=b;
}
void init(){
top1=0;mem(head,-1);
mem(rk,0);mem(dfn,0);mem(low,0);top=0;
sum=0;judge=1;
}
void tarjin(int here){
dfn[here]=low[here]=++tot;
st[++top]=here;instack[here]=1;
GO(i,here){
if(!dfn[to[i]]){
tarjin(to[i]);
low[here]=min(low[here],low[to[i]]);
}
else if(instack[to[i]]){
low[here]=min(low[here],dfn[to[i]]);
}
}
if(low[here]==dfn[here]){
int v=(-1);++sum;
while(top&&v!=here){
v=st[top];--top;
rk[v]=sum;instack[v]=0;
}
}
}
void input(){
init();
cin>>n>>m;
cin.get();
for(int i=1;i<=m;i++){// At least one so add(~1,2) add(~2,1)
char c1[10],c2[10];
int q1(0),bq1,q2(0),bq2;
scanf("%s",c1);scanf("%s",c2);
for(int j=1;j<strlen(c1);++j)
q1=(q1<<1)+(q1<<3)+c1[j]-'0';
for(int j=1;j<strlen(c2);++j)
q2=(q2<<1)+(q2<<3)+c2[j]-'0';
if(c1[0]=='h') q1+=n;
if(c2[0]=='h') q2+=n;
bq1=q1+2*n;bq2=q2+2*n;
add(bq1,q2);add(bq2,q1);
}
for(int i=1;i<=n;i++){
int mi=i,hi=i+n;
int fmi=mi+2*n,fhi=hi+2*n;
add(hi,fmi);add(mi,fhi);
}
}
void xxj(){
for(int i=1;i<=4*n;i++)
if(!dfn[i]) tarjin(i);
for(int i=1;i<=2*n;i++) if(rk[i]==rk[i+2*n]){judge=0;break;}
}
void output(){
if(judge) cout<<"GOOD"<<"\n";
else cout<<"BAD"<<"\n";
}
int main(){
int t;cin>>t;
while(t--){
input();
xxj();
output();
}
return 0;
}