Time Limit: 3000 mSec
Problem Description
Input
The input contains several blocks of test cases. Each case begins with a line containing two integers 1 ≤ n ≤ 100000 and 1 ≤ m ≤ 100000. The number n is the number of astronauts. The next n lines specify the age of the n astronauts; each line contains a single integer number between 0 and 200. The next m lines contains two integers each, separated by a space. A line containing i and j (1 ≤ i,j ≤ n) means that the i-th astronaut and the j-th astronaut hate each other. The input is terminated by a block with n = m = 0.
Output
For each test case, you have to output n lines, each containing a single letter. This letter is either ‘A’, ‘B’, or ‘C’. The i-th line describes which mission the i-th astronaut is assigned to. Astronauts that hate each other should not be assigned to the same mission, only young astronauts should be assigned to Mission B and only senior astronauts should be assigned to Mission A. If there is no such assignment, then output the single line ‘No solution.’ (without quotes).
Sample Input
Sample Output
B C C B C B C B A C C A C A C A
题解:几乎是2-SAT板子题,节点之间的关系稍微复杂了一点,总体来说并不困难。两种人,老年人只能做A,C,年轻人只能做B,C,所以每种人分别对应两种人格(其实就是true和false)如果相互厌恶的两人同类,那么不能同为true,也不能同为false,如果不同类,就只需不同为false(对应C)即可,至于输出方案,mark数组就是答案。
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define REP(i, n) for (int i = 1; i <= (n); i++) 6 #define sqr(x) ((x) * (x)) 7 8 const int maxn = 100000 + 100; 9 const int maxm = 30 + 10; 10 const int maxs = 10000 + 10; 11 12 typedef long long LL; 13 typedef pair<int, int> pii; 14 typedef pair<double, double> pdd; 15 16 const LL unit = 1LL; 17 const int INF = 0x3f3f3f3f; 18 const LL mod = 1000000007; 19 const double eps = 1e-14; 20 const double inf = 1e15; 21 const double pi = acos(-1.0); 22 23 struct TwoSAT 24 { 25 int n, mark[maxn * 2]; 26 vector<int> G[maxn * 2]; 27 int S[maxn * 2], c; 28 29 void init(int n) 30 { 31 this->n = n; 32 memset(mark, 0, sizeof(mark)); 33 for (int i = 0; i < 2 * n; i++) 34 { 35 G[i].clear(); 36 } 37 } 38 39 bool dfs(int x) 40 { 41 if (mark[x ^ 1]) 42 return false; 43 if (mark[x]) 44 return true; 45 46 mark[x] = true; 47 S[c++] = x; 48 for (auto v : G[x]) 49 { 50 if (!dfs(v)) 51 return false; 52 } 53 return true; 54 } 55 56 bool solve() 57 { 58 for (int i = 0; i < 2 * n; i += 2) 59 { 60 if (!mark[i] && !mark[i + 1]) 61 { 62 c = 0; 63 if (!dfs(i)) 64 { 65 while (c > 0) 66 { 67 mark[S[--c]] = 0; 68 } 69 if (!dfs(i + 1)) 70 return false; 71 } 72 } 73 } 74 return true; 75 } 76 77 void add_clause(int x, int xval, int y, int yval) 78 { 79 x = x * 2 + xval; 80 y = y * 2 + yval; 81 G[x ^ 1].push_back(y); 82 G[y ^ 1].push_back(x); 83 } 84 }; 85 86 int n, m, sum; 87 int age[maxn]; 88 TwoSAT solver; 89 90 bool is_young(int x) 91 { 92 return x * n < sum; 93 } 94 95 main() 96 { 97 ios::sync_with_stdio(false); 98 cin.tie(0); 99 //freopen("input.txt", "r", stdin); 100 //freopen("output.txt", "w", stdout); 101 while (cin >> n >> m && (n || m)) 102 { 103 solver.init(n); 104 sum = 0; 105 for (int i = 0; i < n; i++) 106 { 107 cin >> age[i]; 108 sum += age[i]; 109 } 110 int u, v; 111 for (int i = 0; i < m; i++) 112 { 113 cin >> u >> v; 114 if (u == v) 115 continue; 116 u--, v--; 117 if (is_young(age[u]) == is_young(age[v])) 118 { 119 solver.add_clause(u, 0, v, 0); 120 solver.add_clause(u, 1, v, 1); 121 } 122 else 123 { 124 solver.add_clause(u, 1, v, 1); 125 } 126 } 127 if (solver.solve()) 128 { 129 for (int i = 0; i < 2 * n; i += 2) 130 { 131 int a = age[i / 2]; 132 if (a * n >= sum) 133 { 134 if (solver.mark[i]) 135 { 136 cout << "C" << endl; 137 } 138 else 139 { 140 cout << "A" << endl; 141 } 142 } 143 else 144 { 145 if (solver.mark[i]) 146 { 147 cout << "C" << endl; 148 } 149 else 150 { 151 cout << "B" << endl; 152 } 153 } 154 } 155 } 156 else 157 { 158 cout << "No solution." << endl; 159 } 160 } 161 return 0; 162 }