zoukankan      html  css  js  c++  java
  • POJ3678 KATU PUZZLE

    POJ 3678 KATU PUZZLE

    题目大意:

    给定N个点M条边的无向图,每条边的有一个对应的运算符(AND,OR,XOR之一)和一个对应的值(0或1),问是否可以给每个点安排对应的值使得每条边的两个端点的值按照边上的运算符计算得到对应边上的值?

    1 ≤ N ≤ 1000,0 ≤ M ≤ 1,000,000

    ——————————————————————————————————

    比较好的2-SAT题目,可以很好的练习建图!

    a&b=1:~a->a,~b->b

    a&b=0:a->~b,b->~a

    a|b=1:~a->b,~b->a

    a|b=0:a->~a,b->~b

    a^b=0:a->b,b->a,~a->~b,~b->~a

    a^b=1:a->~b,~b->a,~a->b,b->~a

    只里面要注意,a&b=1和a|b=0不存在推导的关系,关系是一定的。所以这样写!!

    ——————————————————————————————————

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cstring>
     5 using namespace std;
     6 const int maxn=1010;
     7 const int maxm=1e6+10;
     8 int n,m;
     9 char s[5];
    10 struct edge
    11 {
    12     int u,v,nxt;
    13 }e[maxm*4];
    14 int head[maxn<<1],js;
    15 void addage(int u,int v)
    16 {
    17     e[++js].u=u;e[js].v=v;
    18     e[js].nxt=head[u];head[u]=js;
    19 }
    20 int dfn[maxn<<1],low[maxn<<1],cnt,st[maxn<<1],top,lt[maxn<<1],lts;
    21 void tarjan(int u)
    22 {
    23     dfn[u]=low[u]=++cnt;
    24     st[++top]=u;
    25     for(int i=head[u];i;i=e[i].nxt)
    26     {
    27         int v=e[i].v;
    28         if(!dfn[v])
    29         {
    30             tarjan(v);
    31             low[u]=min(low[u],low[v]);
    32         }
    33         else if(!lt[v]) low[u]=min(low[u],dfn[v]);
    34     }
    35     if(dfn[u]==low[u])
    36     {
    37         lt[u]=++lts;
    38         while(st[top]!=u)lt[st[top--]]=lts;
    39         --top;
    40     }
    41 }
    42 void init()
    43 {
    44     memset(head,0,sizeof head);
    45     js=0;
    46     memset(dfn,0,sizeof dfn);
    47     memset(low,0,sizeof low);
    48     cnt=top=lts=0;
    49     memset(lt,0,sizeof lt);
    50 }
    51 int main()
    52 {
    53     while(scanf("%d%d",&n,&m)==2)
    54     {
    55         init();
    56         for(int a,b,c,i=1;i<=m;++i)
    57         {
    58             scanf("%d%d%d%s",&a,&b,&c,s);
    59             ++a;++b;
    60             if(s[0]=='A')
    61             {
    62                 if(c==1)addage(a*2,a*2-1),addage(b*2,b*2-1);
    63                 else if(c==0)addage(a*2-1,b*2),addage(b*2-1,a*2);
    64             }
    65             else if(s[0]=='O')
    66             {
    67                 if(c==1)addage(a*2,b*2-1),addage(b*2,a*2-1);
    68                 else if(c==0)addage(a*2-1,a*2),addage(b*2-1,b*2);
    69             }
    70             else
    71             {
    72                 if(c==0)addage(a*2-1,b*2-1),addage(b*2-1,a*2-1),addage(a*2,b*2),addage(b*2,a*2);
    73                 else if(c==1)addage(a*2-1,b*2),addage(b*2,a*2-1),addage(a*2,b*2-1),addage(b*2-1,a*2);
    74             }
    75         }
    76         for(int i=1;i<=n*2;++i)
    77             if(!dfn[i])tarjan(i);
    78         for(int i=1;i<=n;++i)
    79             if(lt[i*2]==lt[i*2-1])
    80             {
    81                 puts("NO");
    82                 return 0;
    83             }
    84         puts("YES");
    85     }
    86     return 0;
    87 }
    View Code
  • 相关阅读:
    有点忙啊
    什么是协程
    HDU 1110 Equipment Box (判断一个大矩形里面能不能放小矩形)
    HDU 1155 Bungee Jumping(物理题,动能公式,弹性势能公式,重力势能公式)
    HDU 1210 Eddy's 洗牌问题(找规律,数学)
    HDU1214 圆桌会议(找规律,数学)
    HDU1215 七夕节(模拟 数学)
    HDU 1216 Assistance Required(暴力打表)
    HDU 1220 Cube(数学,找规律)
    HDU 1221 Rectangle and Circle(判断圆和矩形是不是相交)
  • 原文地址:https://www.cnblogs.com/gryzy/p/10921578.html
Copyright © 2011-2022 走看看