题目链接:https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=0&problem=4137&mosmsg=Submission+received+with+ID+26582526
如果两个互相讨厌的人年龄都是大于或小于 (x) 的,那么他们不能同时选同一种工作,如果年龄一个大于 (x),一个小于 (x),则保证都不选择任务 (C) 即可。因为每个人只能选两个任务,就转化成 (2-SAT) 问题
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 100010;
int n, m;
int age[maxn];
vector<int> G[maxn*2];
int S[maxn*2], c;
bool mark[maxn*2];
bool dfs(int u){
if(mark[u^1]) return false;
if(mark[u]) return true;
mark[u] = true;
S[c++] = u;
for(int i = 0 ; i < G[u].size() ; ++i){
if(!dfs(G[u][i])) return false;
}
return true;
}
bool solve(){
memset(mark, 0, sizeof(mark));
memset(S, 0, sizeof(S));
c = 0;
for(int i = 0 ; i < 2 * n ; 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;
}
ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; }
int main(){
while(scanf("%d%d", &n, &m) == 2 && (n || m)){
for(int i = 0 ; i < 2*n ; ++i) G[i].clear();
double x = 0;
for(int i = 0 ; i < n ; ++i) {
scanf("%d", &age[i]);
x += age[i];
}
x = x / n;
int u, v;
for(int i = 1 ; i <= m ; ++i){
scanf("%d%d", &u, &v);
--u, --v;
if(age[u] >= x && age[v] >= x){
G[u*2].push_back(v*2+1);
G[v*2].push_back(u*2+1);
G[u*2+1].push_back(v*2);
G[v*2+1].push_back(u*2);
} else if(age[u] >= x && age[v] < x){
G[u*2+1].push_back(v*2);
G[v*2+1].push_back(u*2);
} else if(age[u] < x && age[v] >= x){
G[u*2+1].push_back(v*2);
G[v*2+1].push_back(u*2);
} else{
G[u*2].push_back(v*2+1);
G[v*2].push_back(u*2+1);
G[u*2+1].push_back(v*2);
G[v*2+1].push_back(u*2);
}
}
if(solve()){
for(int i = 0 ; i < n ; ++i){
if(mark[i*2]){
printf("%c
", age[i] < x ? 'B' : 'A');
} else{
printf("%c
", 'C');
}
}
} else{
printf("No solution.
");
}
}
return 0;
}