bzoj 1823: [JSOI2010]满汉全席

来源:互联网 发布:javascript模块规范 编辑:程序博客网 时间:2024/04/27 16:00

2-SAT的大水题啊!
因为每一个材料只有两个可能,于是就很模型了啊。
模型是两个不可以都不选

模型二:两者(A,B)不能同时不取
那么选择了A’就只能选择B,选择了B’就只能选择A
连边A’→B,B’→A

于是就可以很愉快地做出这题啦!

#include<cstdio>#include<cstring>const int M=1005*2;const int N=105*2;int T;int n,m;int read (){    char ch=getchar();int x=0;    while (ch<'0'&&ch>'9') ch=getchar();    while (ch>='0'&&ch<='9')    {x=x*10+ch-'0';ch=getchar();}    return x;}struct qq{    int x,y,last;}s[M];int num,last[N];//汉:x   满x+n void init (int x,int y){    num++;    s[num].x=x;s[num].y=y;    s[num].last=last[x];    last[x]=num;}int dfn[N],low[N],belong[N],cnt,sta[N],lalal,shen;bool in[N];int mymin (int x,int y){return x<y?x:y;}void dfs (int x){    dfn[x]=low[x]=++lalal;    sta[++cnt]=x;    in[x]=true;    for (int u=last[x];u!=-1;u=s[u].last)    {        int y=s[u].y;        if (dfn[y]==-1)        {            dfs(y);            low[x]=mymin(low[x],low[y]);        }        else if (in[y]) low[x]=mymin(dfn[y],low[x]);    }    if (low[x]==dfn[x])    {        shen++;        int now;        do        {            now=sta[cnt--];            belong[now]=shen;            in[now]=false;        }while (now!=x);    }}int main(){    scanf("%d",&T);    while (T--)    {        num=0;memset(last,-1,sizeof(last));        scanf("%d%d",&n,&m);        for (int u=1;u<=m;u++)        {            char ch=getchar();int x,y;            while (ch!='m'&&ch!='h') ch=getchar();            x=read();            char ch1=getchar();            while (ch1!='m'&&ch1!='h') ch1=getchar();            y=read();            if (ch=='h'&&ch1=='h') {init(x+n,y);init(y+n,x);  }            if (ch=='h'&&ch1=='m') {init(y,x);  init(x+n,y+n);}            if (ch=='m'&&ch1=='m') {init(x,y+n);init(y,x+n);  }             if (ch=='m'&&ch1=='h') {init(x,y);  init(y+n,x+n);}        }        memset(dfn,-1,sizeof(dfn));        memset(in,false,sizeof(in));        shen=lalal=cnt=0;        for (int u=1;u<=2*n;u++)            if (dfn[u]==-1)                dfs(u);        bool tf=true;        for (int u=1;u<=n;u++)            if (belong[u]==belong[u+n])                {                    tf=false;                    break;                }        if (tf) printf("GOOD\n");        else printf("BAD\n");    }    return 0;}
原创粉丝点击