UVa 1391

题目链接: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;
}
原文地址:https://www.cnblogs.com/tuchen/p/15025394.html