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;
}
posted @ 2017-03-24 11:37  Xiaojian_xiang  阅读(138)  评论(0编辑  收藏  举报