11.6 一道简单2-SAT题 BZOJ1823

来源:互联网 发布:为什么要激活windows 编辑:程序博客网 时间:2024/06/07 03:59

古话说得好啊,“图论只会套模板!”
所以水模板是图论重要的环节!
对的没错,我就是在无耻的水模板!

#include <cstdio>#include <cstring>#include <stack>#define N 10005using namespace std;stack <int> s;int T,n,m,ecnt,indx,cnt,low[N],dfn[N],belong[N];bool ins[N];struct V{    int head;}v[N];struct E{    int u,v,next;}e[N];void init(){    while(!s.empty())s.pop();    memset(low,0,sizeof(low));    memset(dfn,0,sizeof(dfn));    memset(belong,0,sizeof(belong));    memset(ins,false,sizeof(ins));    memset(v,0,sizeof(v));    memset(e,0,sizeof(e));    ecnt=indx=cnt=0;}void add(int x,int y){    e[++ecnt].u=x,e[ecnt].v=y;    e[ecnt].next=v[x].head,v[x].head=ecnt;}void tarjan(int x){    dfn[x]=low[x]=++indx,ins[x]=true,s.push(x);    for(int i=v[x].head;i;i=e[i].next){        int y=e[i].v;        if(!dfn[y])tarjan(y),low[x]=min(low[x],low[y]);        else if(ins[y])low[x]=min(low[x],dfn[y]);    }    if(dfn[x]==low[x]){        cnt++;        while(s.top()!=x){            int t=s.top();s.pop();            ins[t]=false,belong[t]=cnt;        }        int t=s.top();s.pop();        ins[t]=false,belong[t]=cnt;    }}bool sat(){    for(int i=2;i<=2*n+1;i++){        if(!dfn[i])tarjan(i);    }    for(int i=2;i<=2*n+1;i+=2)if(belong[i]==belong[i+1])return false;    return true;}void teste(){    for(int i=1;i<=ecnt;i++){        int u=e[i].u,v=e[i].v;        printf("%d==%d->%d==%d\n",u>>1,u&1,v>>1,v&1);    }    printf("\n");}int main(){    freopen("txt.in","r",stdin);freopen("txt.out","w",stdout);    scanf("%d\n",&T);    while(T--){        init();        scanf("%d %d\n",&n,&m);        char op1,op2;        int x,y;        for(int i=1;i<=m;i++){            scanf("%c%d %c%d\n",&op1,&x,&op2,&y);            //x=1表示x号食材做了满,=0表示做了汉             if(op1=='m'&&op2=='m')add(x<<1,y<<1|1),add(y<<1,x<<1|1);            if(op1=='h'&&op2=='h')add(x<<1|1,y<<1),add(y<<1|1,x<<1);            if(op1=='m'&&op2=='h')add(x<<1,y<<1),add(y<<1|1,x<<1|1);            if(op1=='h'&&op2=='m')add(x<<1|1,y<<1|1),add(y<<1,x<<1);        }        //teste();        if(sat())printf("GOOD\n");        else printf("BAD\n");    }    return 0;}
原创粉丝点击