• 模板 2-sat


    图片来自:http://www.hankcs.com/program/algorithm/poj-3678-katu-puzzle.html

    是蓝书325的2-sat弄下来的模板代码

    lrj老师的代码

    这个可以用来选择字典序最小的

    struct TwoSAT{
        int n;
        vector<int> G[maxn * 2];
        bool mark[maxn * 2];
        int c, s[maxn * 2];///c是表示目前dfs到的个数和已经被标记的集合s
        bool dfs(int x){
            if (mark[x ^ 1]) return false;
            if (mark[x]) return true;
            mark[x] = true;
            s[c++] = x;
            for (int i = 0; i < G[x].size(); i++)
                if (!dfs(G[x][i])) return false;
            return true;
        }
    
        void init(int n){
            this->n = n;
            for (int i = 0; i < 2 * n; i++) G[i].clear();
            memset(mark, 0, sizeof(mark));
        }
        ///利用题目条件找到x和y,即假设x1[0] | x2[1] = false;即:x1[0]|!x2[1]=false
        ///那么我们反转该条件:即x1[1]|!x2[0] = true,即两者任意一个成立即为true
        ///那么我们只要交叉建图即可
        void add_edge(int x, int xval, int y, int yval){
            x = x * 2 + xval, y = y * 2 + yval;
            G[x ^ 1].push_back(y);
            G[y ^ 1].push_back(x);
        }
    
        bool solve(){
            for (int i = 0; i < 2 * n; i += 2){
                if (!mark[i] && !mark[i + 1]){
                    c = 0;
                    if (!dfs(i)){
                        while (c) mark[s[--c]] = false;
                        if (!dfs(i + 1)) return false;
                    }
                }
            }
            return true;
        }
    };
    TwoSAT sat;

    tarjan的,利用强连通的代码

    struct Tarjan{
        int n;
        int pre[maxn*2], low[maxn*2], sccno[maxn*2], dfstime, scc_cnt;
        stack<int> s;
        vector<int> G[maxn*2];
        void init(int n){
            this->n = n;
            for (int i = 0; i <= n * 2; i++) G[i].clear();
            while (!s.empty()) s.pop();
        }
        void add_edge(int x, int y){
            G[x].push_back(y);
        }
        void dfs(int u){
            pre[u] = low[u] = ++dfstime;
            int len = G[u].size();
            s.push(u);
            for (int i = 0; i < len; i++){
                int v = G[u][i];
                if (pre[v] == -1){
                    dfs(v);
                    low[u] = min(low[u], low[v]);
                }
                else if (!sccno[v]){///下面为什么是pre[v]而不是low[v](两者都可以)
                    low[u] = min(low[u], pre[v]);///因为环装最后总会变回来,一样的
                }
            }
            if (low[u] == pre[u]){
                scc_cnt++;
                while (true){
                    int x = s.top(); s.pop();
                    sccno[x] = scc_cnt;
                    if (x == u) break;
                }
            }
            return ;
        }
    
        bool solve(){///看情况修改solve
            memset(pre, -1, sizeof(pre));
            memset(low, 0, sizeof(low));
            memset(sccno, 0, sizeof(sccno));
            dfstime = scc_cnt = 0;
            for (int i = 0; i < 2 * n; i++){
                if (pre[i] == -1) dfs(i);
            }
            for (int i = 0; i < 2 * n; i += 2){///如果两个点在同一个环里面,那么就返回false
                if (sccno[i] == sccno[i + 1]) return false;
            }
            return true;
        }
    };
    Tarjan tar;
  • 相关阅读:
    JavascriptCore中扩展自定义函数
    Qt for Symbian应用的开发转载
    Qt Symbian 开发环境安装转载
    qt屏幕抓图
    为JavascriptCore添加自定义对象
    Tesseract OCR开源项目转载
    Joomla, Wordpress, Drupal 全面详细Pk比较转载
    Drupal,Joomla,Wordpress在内置应用功能方面的区别和比较转载
    Docker:第五章:基于centos7的docker安装配置部署教程以及基于docker Tomcat镜像使用的项目部署教程
    【JavaP6大纲】Redis篇:redis集群工作原理,协议,分布式寻址算法
  • 原文地址:https://www.cnblogs.com/heimao5027/p/6573865.html
Copyright © 2020-2023  润新知