POJ3678:Katu Puzzle 2-SAT

来源:互联网 发布:mac五笔拼音输入法 编辑:程序博客网 时间:2024/05/21 06:38

这题几乎包含了2-SAT的所有常见模型啦。
注意的是如果(A,A’)一定选A,那么就连一条A’->A的边。我也解释不清为什么QAQ。。

#include<iostream>#include<cstdio>#include<cstring>using namespace std;int n,m,cnt,tot,top,scc,flag;int low[2005],dfn[2005],belong[2005],inset[2005],stack[2005],head[2005];int next[4000005],list[4000005];char s[5];inline int read(){    int a=0,f=1; char c=getchar();    while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}    while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}    return a*f;}inline void insert(int x,int y){    next[++cnt]=head[x];    head[x]=cnt;    list[cnt]=y;}void dfs(int x){    low[x]=dfn[x]=++tot;    stack[++top]=x;    inset[x]=1;    for (int i=head[x];i;i=next[i])        if (!dfn[list[i]])        {            dfs(list[i]);            low[x]=min(low[x],low[list[i]]);        }        else if (inset[list[i]]) low[x]=min(low[x],dfn[list[i]]);    if (low[x]==dfn[x])    {        int i=-1; scc++;        while (i!=x)        {            i=stack[top--];            belong[i]=scc;            inset[i]=0;        }    }}inline void tarjan(){    for (int i=1;i<=2*n;i++) if (!dfn[i]) dfs(i);}int main(){    n=read(); m=read();    for (int i=1;i<=m;i++)    {        int u=read()+1,v=read()+1,c=read();        scanf("%s",s);        switch (s[0])        {            case 'A':                if (c==1)                {                    insert(2*u,2*v);                    insert(2*v,2*u);                    insert(2*u-1,2*u);                    insert(2*v-1,2*v);                }                else                {                    insert(2*u,2*v-1);                    insert(2*v,2*u-1);                }                break;            case 'O':                if (c==1)                {                    insert(2*u-1,2*v);                    insert(2*v-1,2*u);                }                else                {                    insert(2*u-1,2*v-1);                    insert(2*v-1,2*u-1);                    insert(2*u,2*u-1);                    insert(2*v,2*v-1);                }                break;            case 'X':                if (c==1)                {                    insert(2*u-1,2*v);                    insert(2*v-1,2*u);                    insert(2*v,2*u-1);                    insert(2*u,2*v-1);                }                else                {                    insert(2*u-1,2*v-1);                    insert(2*v-1,2*u-1);                    insert(2*u,2*v);                    insert(2*v,2*u);                }        }    }    tarjan();    for (int i=1;i<=n;i++)        if (belong[2*i-1]==belong[2*i]) {flag=1; break;}    flag?puts("NO"):puts("YES");    return 0;}
0 0
原创粉丝点击