• http://codeforces.com/contest/776/problem/D 2-sat


    /*2-sat启蒙题目*/
    /*其实2-sat我个人理解就是根据题目写出最终答案必然出现的情况的关系(可能多个) 然后判断能不能构成连通图*/
    
    #include <iostream>
    #include <string.h>
    #include <stdio.h>
    #include <algorithm>
    #include <map>
    #include <set>
    #include <vector>
    #include <stdlib.h>
    #include <math.h>
    #include <string>
    #include <stack>
    #include <queue>
    using namespace std;
    
    const int maxn = 3e5;
    
    int n, m, tot;
    int door[maxn];
    int mark[maxn];
    vector<int>G[maxn];
    vector<int>v[maxn];
    int c = 0;
    int s[maxn];
    
    void addedge(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 dfs(int x) {
        if (mark[x ^ 1]) return false;
        if (mark[x]) return true;
        mark[x] = true;
        s[c++] = x;
        int len = G[x].size();
        for (int i = 0; i < len; ++i) {
            if (!dfs(G[x][i]))
                return false;
        }
        return true;
    }
    
    bool solve() {
        for (int i = 0; i < m * 2; i += 2) {
            if (!mark[i] && !mark[i + 1]) {
                c = 0;
                if (!dfs(i)) {
                    while (c > 0) mark[s[--c]] = false;
                    if (!dfs(i + 1)) return false;
                }
            }
        }
        return true;
    }
    
    void test() {
        ios::sync_with_stdio(false);
        cin >> n >> m;
        for (int i = 0; i < n; ++i) cin >> door[i];
        for (int i = 0; i < m; ++i) {
            int x; cin >> x;
            for (int j = 0; j < x; ++j) {
                int y; cin >> y;
                v[y - 1].push_back(i);
            }
        }
        for (int i = 0; i < m * 2; ++i)
            G[i].clear();
        memset(mark, 0, sizeof mark);
        for (int i = 0; i < n; ++i) {
            if (door[i]) {
                addedge(v[i][0], 0, v[i][1], 1);
                addedge(v[i][0], 1, v[i][1], 0);
            }
            else {
                addedge(v[i][0], 0, v[i][1], 0);
                addedge(v[i][0], 1, v[i][1], 1);
            }
        }
        cout << (solve() ? "YES" : "NO") << endl;
    }
    
    
    int main() {
        test();
        return 0;
    }
  • 相关阅读:
    MSSQL_打开xp_cmdshell
    想在win7 32bit的情况下装个64位虚拟机的想法
    查看系统已运行了多久
    sql弄个表结构出来..
    在win下的cmd 的find
    告别google.com.hk的龟速
    VC常用数据类型使用转换详解
    C++中的文件输入/输出ios:xx eat Processing(zz)
    X86汇编语言学习手记(1)
    程序员数据结构笔记
  • 原文地址:https://www.cnblogs.com/boson-is-god/p/6477074.html
Copyright © 2020-2023  润新知