• [POI2001] 和平委员会 Peaceful Commission——2-sat(dfs构造字典序最小解)


    题面

      HDU1814

    解析

      2-sat裸题, 求字典序最小的解

      我一开始试图用拓扑序求字典序最小的解,YY了一阵,打完代码,无论如何都要WA,于是弃疗了,至今不知为什么会错,也许是我太菜了吧,于是学习了一下dfs构造字典序最小解的方法,时间复杂度是O(nm)的

      基本思路同拓扑序构造可行解一样,用染色法。但dfs是直接在原图中跑的,因此要传递选择的标记,也就是颜色。从小到大对每一个没有染色的点$j$尝试染上选择的颜色,在对称点$j'$(点$j$的编号小于点$j'$的编号)上染上不选的颜色,传递选择颜色时如果没有遇到不选的颜色,说明染色方案成功,否则失败,再给点$j'$染上选择的颜色 ,点$j$染上不选的颜色,进行相同操作,如果仍然失败,则说明该情况没有可行解。

      HDU上有一个坑点:多组数据。(我的英语菜得不谈,这个东西搞了我半个小时)

     代码:

    #include<cstdio>
    #include<vector>
    using namespace std;
    const int maxn = 8006;
    
    int n, m, stak[maxn], top, col[maxn<<1];
    vector<int> G[maxn<<1];
    
    int mir(int x)
    {
        return x&1? x+1: x-1;
    }
    
    bool paint(int x)
    {
        if(col[x])
            return col[x] == 1;
        col[x] = 1;col[mir(x)] = 2;
        stak[++top] = x;
        for(unsigned int i = 0; i < G[x].size(); ++i)
        {
            int id = G[x][i];
            if(!paint(id))
                return 0;
        }
        return 1;
    }
    
    bool work()
    {
        for(int i = 1; i <= (n<<1); ++i)
            if(!col[i])
            {
                top = 0;
                if(!paint(i))
                {
                    while(top)  col[stak[top]] = col[mir(stak[top])] = 0, top--;
                    if(!paint(mir(i)))
                        return 0;
                }
            }
        return 1;
    }
    
    int main()
    {
        while(scanf("%d%d", &n, &m) != EOF)
        {
            for(int i = 1; i <= m; ++i)
            {
                int x, y;
                scanf("%d%d", &x, &y);
                G[x].push_back(mir(y));
                G[y].push_back(mir(x));
            }
            if(work())
            {
                for(int i = 1; i <= (n<<1); ++i)
                    if(col[i] == 1)
                        printf("%d
    ", i);
            }
            else
                printf("NIE
    ");
            for(int i = 1; i <= (n<<1); ++i)
                G[i].clear(), col[i] = 0;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    java中的成员变量和局部变量
    多线程实现输出当前时间,和猜数字游戏
    JDBC
    jQuery和原生JS的对比
    JavaScript有趣的知识点
    MySQL的数据类型
    行级元素和块级元素
    重定向和请求转发的区别
    JSP九大内置对象
    Python练习
  • 原文地址:https://www.cnblogs.com/Joker-Yza/p/11312672.html
Copyright © 2020-2023  润新知