蓝书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; }