• 【2-SAT】POJ3678-Katu Puzzle


    【题目大意】

    给出有向图G(V, E),每条边(a,b)有一个值c(c=0或1)和运算符op,问能否找到这一张有向图,满足所有的a op b=c?

    【思路】

    显然是2-SAT。不过要注意一定,如a and b=1,若a=0是必定无解的。像这种情况,要连边a+n->a;同理所有类似于a or b=0,也要两边a->a+n。即无解清新要保证自己连到自己的相反情形。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<vector>
     6 #include<stack>
     7 using namespace std;
     8 const int MAXN=1000+50;
     9 vector<int> E[MAXN];
    10 stack<int> s;
    11 int low[MAXN],dfn[MAXN],cnt=0,bcnt=0;
    12 int instack[MAXN],b[MAXN];
    13 int n,m;
    14 
    15 void addedge(int u,int v)
    16 {
    17     E[u].push_back(v);
    18 }
    19 
    20 void tarjan(int u)
    21 {
    22     dfn[u]=low[u]=++cnt;
    23     instack[u]=1;
    24     s.push(u);
    25     for (int i=0;i<E[u].size();i++)
    26     {
    27         int to=E[u][i];
    28         if (!instack[to]) tarjan(to),low[u]=min(low[u],low[to]);
    29             else if (instack[to]==1) low[u]=min(low[u],dfn[to]);
    30     }
    31     
    32     if (dfn[u]==low[u])
    33     {
    34         int x;
    35         ++bcnt;
    36         do
    37         {
    38             x=s.top();s.pop();
    39             instack[x]=2;
    40             b[x]=bcnt;
    41         }while (x!=u);
    42     }
    43 }
    44 
    45 void init()
    46 {
    47     scanf("%d%d",&n,&m);
    48     for (int i=0;i<m;i++)
    49     {
    50         int a,b,c;char op[5];
    51         scanf("%d%d%d%s",&a,&b,&c,op);
    52         a++,b++;
    53         if (op[0]=='A')
    54         {
    55             if (c==0) addedge(a,b+n),addedge(b,a+n);
    56             if (c==1) addedge(a,b),addedge(b,a),addedge(a+n,a),addedge(b+n,b);
    57         }
    58         if (op[0]=='O')
    59         {
    60             if (c==0) addedge(a+n,b+n),addedge(b+n,a+n),addedge(a,a+n),addedge(b,b+n);
    61             if (c==1) addedge(a+n,b),addedge(b+n,a);
    62         }
    63         if (op[0]=='X')
    64         {
    65             if (c==0) addedge(a,b),addedge(b,a),addedge(a+n,b+n),addedge(b+n,a+n);
    66             if (c==1) addedge(a+n,b),addedge(b+n,a),addedge(a,b+n),addedge(b,a+n); 
    67         }
    68     }
    69 }
    70 
    71 void solve()
    72 {
    73     memset(instack,0,sizeof(instack));
    74     for (int i=1;i<=2*n;i++) if (!instack[i]) tarjan(i); 
    75     int flag=1;
    76     for (int i=1;i<=n;i++)
    77         if (b[i]==b[i+n])
    78         {
    79             flag=0;
    80             break;
    81         }
    82     puts(flag?"YES":"NO");
    83 }
    84 
    85 int main()
    86 {
    87     init();
    88     solve();
    89     return 0;
    90 }
  • 相关阅读:
    iis6 , URL重写HTM文件名后,出现真实的HTM文件不能访问的解决
    pe如何安装ios系统
    ASP.NET Word转为PDF
    asp.net 操作word 权限
    windows server 2008 r2 修改远程登入的端口号(3389)
    A
    A Bug
    亲戚
    Kruskal
    HDOJ ——统计难题
  • 原文地址:https://www.cnblogs.com/iiyiyi/p/5709900.html
Copyright © 2020-2023  润新知