[蓝书/Ch5] Astronauts UVALive

来源:互联网 发布:剔除异常数据的方法 编辑:程序博客网 时间:2024/05/20 04:15

题目链接

根据题意推出 任意ij至少有一个为true (i || j) 表示 , 同类应该一个true一个false可以用  (i || j)  &&  (!i || !j) 表示
#include<bits/stdc++.h>using namespace std;typedef long long ll;const int maxn = 100000 + 5;struct TwoSAT {  int n;  vector<int> G[maxn*2];  bool mark[maxn*2];  int S[maxn*2], c;  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;  }  void init(int n) {    this->n = n;    for (int i = 0; i < n*2; i++) G[i].clear();    memset(mark, 0, sizeof(mark));  }  // x = xval or y = yval  void add_clause(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 solve() {    for(int i = 0; i < n*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;  }};TwoSAT solver;int n,m;int a[maxn];int sum=0;int is_young(int x) {  return a[x] * n < sum;}int main(){//    freopen("data.txt","r",stdin);    ios_base::sync_with_stdio(false);    while(cin >> n>>m)    {        if(n==0) break;        sum=0;        solver.init(n);        for(int i = 0; i < n; i++)        {            cin >> a[i];            sum += a[i];        }        solver.init(n);        for(int i = 0; i < m; i++)        {            int a, b;            cin >> a>>b;            a--; b--;            if(a == b) continue;            solver.add_clause(a, 1, b, 1); // 不能同去任务C            if(is_young(a) == is_young(b)) // 同类宇航员                solver.add_clause(a, 0, b, 0); // 不能同去任务A或者任务B        }        if(!solver.solve()) printf("No solution.\n");        else for(int i = 0; i < n; i++)          if(solver.mark[i*2]) printf("C\n"); // x[i]=false,去任务C          else if(is_young(i)) printf("B\n"); // x[i]=true的年轻宇航员去任务B          else printf("A\n"); // x[i]=true的年长宇航员去任务A      }    return 0;}
原创粉丝点击