• 2-sat 分类讨论 UVALIVE 3713


    蓝书326

    //看看会不会爆int!数组会不会少了一维!
    //取物问题一定要小心先手胜利的条件
    #include <bits/stdc++.h>
    using namespace std;
    #pragma comment(linker,"/STACK:102400000,102400000")
    #define LL long long
    #define ALL(a) a.begin(), a.end()
    #define pb push_back
    #define mk make_pair
    #define fi first
    #define se second
    #define haha printf("haha
    ")
    const int maxn = 1e5 + 5;
    struct TwoSat{
        int n, c, s[maxn * 2];
        bool mark[maxn << 1];
        vector<int> G[maxn << 1];
    
        void init(int n){
            this->n = n;
            for (int i = 0; i < 2 * n; i++) G[i].clear();
            memset(mark, false, sizeof(mark));
        }
    
        void add_edge(int x, int xval, int y, int yval){
            x = x * 2 + xval, y = y * 2 + yval;
            G[x ^ 1].pb(y), G[y ^ 1].pb(x);
        }
    
        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;
        }
    
        bool solve(){
            for (int i = 0; i < n * 2; 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 sat2;
    int n, m;
    int age[maxn];
    
    int main(){
        while (scanf("%d%d", &n, &m) && (n + m) > 0){
            sat2.init(n);
            int tot = 0;
            for (int i = 0; i < n; i++){
                scanf("%d", age + i);
                tot += age[i];
            }
    /*
    假设A和B都是1,C是0
    if两者属于同一个任务,那么,两者不能分配到同一个任务,
    所以两者不能同时为true和同时为false
    
    if两者属于不同的任务,那么两者不能同时为false
    */
            for (int i = 0; i < m; i++){
                int u, v; scanf("%d%d", &u, &v);
                u--, v--;
                if (u == v) continue;
                int tyu = age[u] * n < tot, tyv = age[v] * n < tot;
                sat2.add_edge(u, 1, v, 1);
                if (tyu == tyv)
                    sat2.add_edge(u, 0, v, 0);
            }
            if (!sat2.solve()) puts("No solution.");
            else {
                for (int i = 0; i < n; i++){
                    if (sat2.mark[i * 2]) puts("C");
                    if (sat2.mark[i * 2 + 1]) {
                        if (age[i] * n < tot) puts("B");
                        else puts("A");
                    }
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    【转载】$.ajax()方法详解
    【转载】"从客户端中检测到有潜在危险的 Request.Form 值"的解决方案汇总
    jQuery获取select的选中项value和text
    AIDL
    SAX
    AsyncTask
    Handler
    ViewSwitch
    TabActivity
    AlarmManager
  • 原文地址:https://www.cnblogs.com/heimao5027/p/6574079.html
Copyright © 2020-2023  润新知