HDU4115.Eliminate the Conflict(剪刀石头布)——2-sat可行性判断

来源:互联网 发布:java中构造方法的使用 编辑:程序博客网 时间:2024/05/17 23:05

http://acm.hdu.edu.cn/showproblem.php?pid=4115

题目描述:
Bob,和Alice两人进行n轮的剪刀石头布,已知Bob n轮的出的情况,对于Alice给出m组的限制,只要每轮Alice没输,n轮之后就算Alice赢。判断她是否能赢

分析:
对于第i轮Bob出的情况,则alice有两种选择(相当于第i个变量有两种状态),然后我们只要处理矛盾边即可

//62MS  2156K   3312 B#include<cstring>#include<cstdio>#include<queue>#include<vector>#include<iostream>const int MAXN=20010;const int MAXM=40010;using namespace std;int low[MAXN],dfn[MAXN],sccno[MAXN],scc,dfs_clock,top;int Stack[MAXN];bool instack[MAXN];struct Edge {    int to,next;} edge[MAXM<<1];int head[MAXN],tot;void addedge(int u,int v){    edge[tot].to=v;edge[tot].next=head[u];head[u]=tot++;}void init(){    tot=0;    memset(head,0xff,sizeof(head));}void dfs(int u){    int v;    low[u]=dfn[u]=++dfs_clock;    instack[u]=1;    Stack[top++]=u;    for(int i=head[u]; i!=-1; i=edge[i].next) {        v=edge[i].to;        if(!dfn[v]) {            dfs(v);            if(low[u]>low[v])                low[u]=low[v];        } else if(instack[v]&&low[u]>dfn[v])            low[u]=dfn[v];    }    if(low[u]==dfn[u]) {        scc++;        for(;;) {            v=Stack[--top];            instack[v]=0;            sccno[v]=scc;            if(v==u) break;        }    }}bool solveable(int n){    memset(dfn,0,sizeof(dfn));    memset(instack,false,sizeof(instack));    dfs_clock=top=scc=0;    for(int i=0; i<n; ++i) {        if(!dfn[i]) dfs(i);    }    for(int i=0; i<n; i+=2) {        if(sccno[i]==sccno[i^1]) return false;    }    return true;}int main(){#ifndef ONLINE_JUDGEfreopen("in.txt","r",stdin);#endif // ONLINE_JUDGE    int T,n,m,u,v,c,cas=1;    int a[MAXN],b[MAXN][2];    scanf("%d",&T);    while(T--){        scanf("%d%d",&n,&m);        for(int i=0;i<n;++i){            scanf("%d",&a[i]);            if(a[i]==1){                b[i][0]=1;b[i][1]=2;            }            if(a[i]==2){                b[i][0]=2;b[i][1]=3;            }            if(a[i]==3){                b[i][0]=3;b[i][1]=1;            }        }        init();        while(m--){            scanf("%d%d%d",&u,&v,&c);            u--,v--;            if(c==0){                if(b[u][0]!=b[v][0]){                    addedge(u<<1,v<<1|1);                    addedge(v<<1,u<<1|1);                }                if(b[u][0]!=b[v][1]){                    addedge(u<<1,v<<1);                    addedge(v<<1|1,u<<1|1);                }                if(b[u][1]!=b[v][0]){                    addedge(u<<1|1,v<<1|1);                    addedge(v<<1,u<<1);                }                if(b[u][1]!=b[v][1]){                    addedge(u<<1|1,v<<1);                    addedge(v<<1|1,u<<1);                }            }else{                if(b[u][0]==b[v][0]){                    addedge(u<<1,v<<1|1);                    addedge(v<<1,u<<1|1);                }                if(b[u][0]==b[v][1]){                    addedge(u<<1,v<<1);                    addedge(v<<1|1,u<<1|1);                }                if(b[u][1]==b[v][0]){                    addedge(u<<1|1,v<<1|1);                    addedge(v<<1,u<<1);                }                if(b[u][1]==b[v][1]){                    addedge(u<<1|1,v<<1);                    addedge(v<<1|1,u<<1);                }            }        }        printf("Case #%d: ",cas++);        if(solveable(n<<1)) puts("yes");        else puts("no");    }    return 0;}
0 0
原创粉丝点击