zoukankan      html  css  js  c++  java
  • poj3678 Katu Puzzle

    强联通没啥好写的,写写2-sat的题解算了。

    拆点,一个表示这个数取0,另一个表示取1

    2-sat边的意义是选了x,就必须选y。

    那么分情况讨论建边即可。值得注意的是,假如是and运算,答案为0,那么1必然不能选,那么让当前位置的1节点连向自己的0节点,直接产生不合法情况。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    struct node
    {
        int x,y,next;
    }a[8100000];int len,last[2100];
    void ins(int x,int y)
    {
        len++;
        a[len].x=x;a[len].y=y;
        a[len].next=last[x];last[x]=len;
    }
    int z,dfn[2100],low[2100];
    int top,sta[2100];bool v[2100];
    int cnt,bel[2100];
    void SCC(int x)
    {
        dfn[x]=low[x]=++z;
        sta[++top]=x;v[x]=true;
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(dfn[y]==0)
            {
                SCC(y);
                low[x]=min(low[x],low[y]);
            }
            else if(v[y]==true)
                low[x]=min(low[x],dfn[y]);
        }
        if(low[x]==dfn[x])
        {
            int k;cnt++;
            do
            {
                k=sta[top];top--;
                v[k]=false;
                bel[k]=cnt;
            }while(k!=x);
        }
    }
    
    int n,m;
    void conposition()
    {
        int x,y,z;char ss[10];
        len=0;memset(last,0,sizeof(last));
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d%s",&x,&y,&z,ss+1);x++,y++;
            if(ss[1]=='A')
            {
                if(z==0)
                    ins(x+n,y), ins(y+n,x);
                else
                    ins(x,x+n), ins(y,y+n);
            }
            else if(ss[1]=='O')
            {
                if(z==0)
                    ins(x+n,x), ins(y+n,y);
                else
                    ins(x,y+n), ins(y,x+n);
            }
            else
            {
                if(z==0)
                    ins(x,y), ins(x+n,y+n),
                    ins(y,x), ins(y+n,x+n);
                else
                    ins(x,y+n), ins(x+n,y),
                    ins(y,x+n), ins(y+n,x);
            }
        }
    }
    int main()
    {
        scanf("%d%d",&n,&m);conposition();
        z=top=cnt=0;
        for(int i=1;i<=2*n;i++)
            if(dfn[i]==0)SCC(i);
        for(int i=1;i<=n;i++)
            if(bel[i]==bel[i+n]){printf("NO
    ");return 0;}
        printf("YES
    ");
        return 0;
    }
  • 相关阅读:
    Sum Root to Leaf Numbers——LeetCode
    Search a 2D Matrix ——LeetCode
    Surrounded Regions——LeetCode
    Palindrome Partitioning——LeetCode
    Reverse Linked List II——LeetCode
    Word Break II——LeetCode
    POJ1163——The Triangle
    3Sum Closest——LeetCode
    House Robber——LeetCode
    amqp 抓包
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/9540828.html
Copyright © 2011-2022 走看看