【HDU1814】Peaceful Commission(2-sat+暴力染色)

传送门

(2-sat)的模板题,首先得出题目中的二元关系为:对于有矛盾的(x_i,x_j),至多选择一个,那么连边(x_i ightarrow x_j',x_j ightarrow x_i')
在这里这个关系是明确的关系,我们连边时只用连明确的关系即可。假设不选(x_i),我们也不知道(x_j)选不选,可选可不选,所以不用从(x_i')出发连边。

然后题目因为要求字典序最小,据说(trajan)缩点那样搞可能出问题,因为数据范围比较小,所以直接(O(nm))暴力染色就行了QAQ
代码如下:

/*
 * Author:  heyuhhh
 * Created Time:  2019/11/29 14:52:58
 */
#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <cstring>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
  #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  void err() { std::cout << '
'; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
  #define dbg(...)
#endif
void pt() {std::cout << '
'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 8005;

int n, m;
vector <int> g[N << 1];

int get(int x) {
    if(x % 2) return x + 1;
    return x - 1;
}

int cnt;
int col[N << 1], tmp[N];

bool paint(int x) {
    if(col[x]) {
        if(col[x] % 2 == 0) return false;
        return true;   
    }
    tmp[++cnt] = x;
    col[x] = 1; col[get(x)] = 2;
    for(auto y : g[x]) {
        if(!paint(y)) return false;   
    }
    return true;
}

bool work() {
    memset(col, 0, sizeof(col));
    for(int i = 1; i <= 2 * n; i++) {
        if(col[i]) continue;
        cnt = 0;
        if(!paint(i)) {
            for(int j = 1; j <= cnt; j++) col[tmp[j]] = col[get(tmp[j])] = 0;
            cnt = 0;
            if(!paint(get(i))) return false; 
        }
    }
    return true;
}

void run(){
    for(int i = 1; i <= 2 * n; i++) g[i].clear();
    for(int i = 1; i <= m; i++) {
        int u, v; cin >> u >> v;
        g[u].push_back(get(v));
        g[v].push_back(get(u));
        g[get(u)].push_back(v);
        g[get(v)].push_back(u);
    }
    if(work()) {
        for(int i = 1; i <= 2 * n; i++) 
            if(col[i] == 1) cout << i << '
';
    } else cout << "NIE" << '
';
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    while(cin >> n >> m) run();
    return 0;
}
原文地址:https://www.cnblogs.com/heyuhhh/p/11965770.html