zoukankan      html  css  js  c++  java
  • 2017-2018 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) M

    题目大意:给你 m 个式子, 问你最少再添加多少式子能使没有任何一种赋值方式使全部的式子为真。 并且在你给的式子中不能有非。

    思路:根据题目给的m个式子可以建出2-Sat的图, 现在问你最少加多少个边使得2-Sat不成立, 我们可以发现我们给出的式子肯定是 a | a

    的形式, 在题目中没有 ~p | ~q这种形式必定无解, 否则最多增加2式子就能完成, 我们枚举a, 取check如果所有都不行就输出2。

    #include<bits/stdc++.h>
    #define LL long long
    #define fi first
    #define se second
    #define mk make_pair
    #define PLL pair<LL, LL>
    #define PLI pair<LL, int>
    #define PII pair<int, int>
    #define SZ(x) ((int)x.size())
    #define ull unsigned long long
    
    using namespace std;
    
    const int N = 4000 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9 + 7;
    const double eps = 1e-8;
    const double PI = acos(-1);
    
    int n, m;
    bool flag;
    int scc[N], stk[N], dfn[N], low[N], tot, cnt, idx;
    bool in[N];
    vector<int> G[N];
    
    void tarjan(int u) {
        dfn[u] = low[u] = ++idx;
        stk[++tot] = u, in[u] = true;
        for(int v : G[u]) {
            if(!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
            else if(in[v]) low[u] = min(low[u], dfn[v]);
        }
        if(dfn[u] == low[u]) {
            cnt++;
            while(1) {
                int now = stk[tot--];
                scc[now] = cnt;
                in[now] = false;
                if(now == u) break;
            }
        }
    }
    
    int main() {
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= m; i++) {
            int u, v; scanf("%d%d", &u, &v);
            if(u < 0 && v < 0) flag = true;
            if(u < 0) u = n - u;
            if(v < 0) v = n - v;
            if(u <= n) G[u+n].push_back(v);
            else G[u-n].push_back(v);
            if(v <= n) G[v+n].push_back(u);
            else G[v-n].push_back(u);
        }
        for(int i = 1; i <= n<<1; i++)
            if(!dfn[i]) tarjan(i);
        for(int i = 1; i <= n; i++)
            if(scc[i] == scc[i+n])
                return puts("0"), 0;
        if(!flag) return puts("-1"), 0;
        for(int i = 1; i <= n; i++, cnt = 0, idx = 0) {
            G[i+n].push_back(i);
            for(int j = 1; j <= n<<1; j++) dfn[j] = 0;
            for(int j = 1; j <= n<<1; j++) if(!dfn[j]) tarjan(j);
            for(int j = 1; j <= n; j++)
                if(scc[j] == scc[j+n])
                    return puts("1"), 0;
            G[i+n].pop_back();
        }
        puts("2");
        return 0;
    }
    
    /*
    */
  • 相关阅读:
    女程序员发的一条微博
    【转】Android中JNI的使用方法
    【转】浏览器~加载,解析,渲染
    【转】PHP简单拦截器的实现
    【转】jQuery选择器总结
    【转】JS跨域(ajax跨域、iframe跨域)解决方法及原理详解(jsonp)
    【转】JSONP跨域的原理解析
    utuntu16.04安装tensorflow1.4-gpu
    Kaggle-Digit Recognizer
    python 常见细节知识点
  • 原文地址:https://www.cnblogs.com/CJLHY/p/10225668.html
Copyright © 2011-2022 走看看