当u, v 年龄段一样时,假设都大于平均年龄,必须满足u=A&&v=C || u=C&&v=A,我们只要加(u=A||v=A) &&(u=C||v=C)两个条件就可以了。而当年龄段不同时只加,(u=A||v=B)这个条件就可以了。
#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define LL long long
#define CLR(a, b) memset(a, b, sizeof(a))
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 100100;
int age[maxn];
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();
CLR(mark, 0);
}
///x == xval or y == yval
void add(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;
}
void choose(int x)
{
for(int i = 0; i < n * 2; i += 2)
{
if(mark[i])
{
if(age[i / 2] < x) puts("B");
else puts("A");
}
else puts("C");
}
}
} sol;
int main()
{
int n, m;
while(scanf("%d%d", &n, &m), n + m)
{
int tot = 0;
for(int i = 0; i < n; i ++)
{
scanf("%d", &age[i]);
tot += age[i];
}
tot = (tot + n - 1) / n;sol.init(n);
for(int i = 0; i < m; i ++)
{
int u, v;
scanf("%d%d", &u, &v);
u --; v --;
if(age[u] < tot && age[v] < tot)
{
sol.add(u, 1, v, 1);
sol.add(u, 0, v, 0);
}
else if(age[u] < tot && age[v] >= tot)
sol.add(u, 0, v, 0);
else if(age[u] >= tot && age[v] >= tot)
{
sol.add(u, 1, v, 1);
sol.add(u, 0, v, 0);
}
else if(age[u] >= tot && age[v] < tot)
sol.add(u, 0, v, 0);
}
if(!sol.solve())
puts("No solution.");
else
{
sol.choose(tot);
}
}
}