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\n")
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;
}

 

posted @ 2017-03-18 14:49  知る奇迹に  阅读(140)  评论(0编辑  收藏  举报