根据题意推出 任意i和j至少有一个为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;
}