• [poj 3678]Katu Pazzle[2-SAT常用建图法]


    题意:

    不说了..典型的2-SAT

    常用模型:

    重点:

    突出"绑定性".

    连线表示限制而非可行. 因为最后要求对立点不在同一强连通分量是说同一强连通中的点必须同时选.


    坑:

    首先是算法记错了...inq是求SPFA用的...

    Tarjan中也少了个灰色点黑色点的判断(本身算是查漏补缺吧, 以后检查的时候首先还是看看模板有没有背错)...

    分身点加的是点的个数.

    异或0的那个判断粗心了...

    还是默认多组样例吧...


    #include <cstdio>
    #include <cstring>
    #include <stack>
    #include <algorithm>
    #include <string>
    #include <iostream>
    using namespace std;
    const int MAXN = 1005;
    const int MAXE = 1000005;
    struct pool
    {
        int v,pre;
    } p[MAXE<<2];
    int n,m;
    int head[MAXN<<1],num,dfn[MAXN<<1],low[MAXN<<1],id[MAXN<<1],size,Index;
    bool used[MAXN<<1];
    stack<int> s;
    void clear()
    {
        memset(head,0,sizeof(head));
        memset(dfn,0,sizeof(dfn));
        memset(low,0,sizeof(low));
        memset(used,false,sizeof(used));
        while(!s.empty()) s.pop();
        num = Index = size = 0;
    }
    
    void add(int u, int v)
    {
        p[++num].v = v;
        p[num].pre = head[u];
        head[u] = num;
    }
    
    void build(int u, int v, bool c, string s)
    {
        if(s=="AND")
        {
            if(c)
            {
                add(u+n,u);
                add(v+n,v);
            }
            else
            {
                add(u,v+n);
                add(v,u+n);
            }
        }
        else if(s=="OR")
        {
            if(c)
            {
                add(u+n,v);
                add(v+n,u);
            }
            else
            {
                add(u,u+n);
                add(v,v+n);
            }
        }
        else
        {
            if(c)
            {
                add(u,v+n);
                add(v,u+n);
                add(v+n,u);
                add(u+n,v);
            }
            else
            {
                add(u,v);
                add(u+n,v+n);
                add(v,u);
                add(v+n,u+n);
            }
        }
    }
    void Tarjan(int u)
    {
        dfn[u] = low[u] = ++Index;
        used[u] = true;
        s.push(u);
        for(int tmp=head[u],k; k=p[tmp].v,tmp; tmp=p[tmp].pre)
        {
            if(!dfn[k])
            {
                Tarjan(k);
                low[u] = min(low[u],low[k]);
            }
            else if(used[k]) low[u] = min(low[u],dfn[k]);//!!
        }
        if(dfn[u] == low[u])
        {
            size++;
            int k;
            do
            {
                k = s.top();
                s.pop();
                // printf("node = %d size = %d
    ",k,size);
                used[k] = false;
                id[k] = size;
            }
            while(u!=k);
        }
    }
    
    int main()
    {
        while(scanf("%d %d",&n,&m)==2)
        {
            string s;
            bool c;
            clear();
            for(int i = 0,u,v; i<m; i++)
            {
                cin>>u>>v>>c>>s;
                build(u,v,c,s);
            }
            for(int i=0; i<n<<1; i++) //每一种状态都要试一遍
            {
                if(!dfn[i])
                    Tarjan(i);
            }
            bool flag = true;
            for(int i=0; i<n; i++)
                if(id[i]==id[i+n])
                {
                    flag = false;
                    // printf("and %d
    ",i);
                    break;
                }
            if(flag)    printf("YES
    ");
            else        printf("NO
    ");
        }
    }
    


  • 相关阅读:
    【BZOJ2288】生日礼物 [贪心]
    Tinyhttpd阅读笔记
    数据结构-图-经典算法(三)
    数据结构-图-经典算法(二)
    数据结构-图-经典算法(一)
    TCP协议的滑动窗口协议以及流量控制
    2016腾讯实习电话面试总结---2016-03-10
    B树,B+树,B*树
    平衡二叉树(AVL树)
    二叉搜索树(二叉查找树,二叉排序树)
  • 原文地址:https://www.cnblogs.com/pangblog/p/3275764.html
Copyright © 2020-2023  润新知