UVA 1391
题目链接:
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=38529
题意:
n个人,年龄在均值以下的去A或C,以上去B或C。
有m中仇恨方式,问一种合理的方案并输出。
思路:
2-SAT
我没有看题解哦
我没有看题解哦
我没有看题解哦
我没有看题解哦~
刚开始想怎么去处理三种状态,然后按照之前打版的方法打了一发连样例都没有过。
然后把加边的地方lin[u^1].push_back(v)改成lin[u].push_back(v^1)。居然过样例了。嗯WA了。
想了想是不是因为对于每个点属于A或者B的情况、即取他为TRUE的情况都没有点接在后面,每次dfs就直接赋值为TRUE。试着翻转了一下每个点为TRUE的状态,即设0为FALSE,1为TRUE。WA。
玩了两分钟手机,决定从原理上想一想。
2-SAT的原理是数理逻辑。假设A或B真,则A假时B一定真,B假时A一定真,然而A真B真的情况也是存在的。但本题存在A真B真都不合法的情况,就是A和B的年龄都在一个年龄段上时。
关键代码:
if(age[u/2] == age[v/2]){
lin[u].push_back(v^1);
lin[v].push_back(u^1);
}
然后就A了,WA了四发吧,可以去打省赛了。
源码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int MAXN = 100000 + 5;
vector
stack
int n, m;
int age[MAXN];
int valid[MAXN * 2];
double ave;
bool dfs(int u)
{
if(valid[u^1]) return false;
if(valid[u]) return true;
valid[u] = 1;
sta.push(u);
for(int i = 0 ; i < (int)lin[u].size() ; i++){
int v = lin[u][i];
if(!dfs(v)) return false;
}
return true;
}
bool solve()
{
while(!sta.empty()) sta.pop();
memset(valid, 0, sizeof(valid));
for(int i = 0 ; i < 2 * n ; i+=2){
if(!valid[i] && !valid[i^1]){
if(!dfs(i)){
while(!sta.empty()){
int org = sta.top(); sta.pop();
valid[org] = 0;
if(org == i) break;
}
if(!dfs(i^1)) return false;
}
}
}
return true;
}
int main()
{
while(scanf("%d%d", &n, &m) != EOF && n + m){
ave = 0;
for(int i = 0 ; i < n ; i++)
scanf("%d", &age[i]), ave += age[i];
for(int i = 0 ; i < 2 * n ; i++)
lin[i].clear();
ave /= (1.0 * n);
for(int i = 0 ; i < n ; i++){
if(age[i] >= ave) age[i] = 0;
else age[i] = 1;
}
int u, v;
for(int i = 1 ; i <= m ; i++){
scanf("%d%d", &u, &v);
u--, v--;
u *= 2, v *= 2;
lin[u^1].push_back(v);
lin[v^1].push_back(u);
if(age[u/2] == age[v/2]){
lin[u].push_back(v^1);
lin[v].push_back(u^1);
}
}
// for(int i = 0 ; i < 2 * n ; i++){
// printf("lin[%d] = ", i) ;
// for(int j = 0 ; j < (int)lin[i].size() ; j++)
// printf("%d ", lin[i][j]);
// printf("\n");
// }
if(solve()){
for(int i = 0 ; i < 2 * n ; i += 2){
if(valid[i]){
if(!age[i / 2]) printf("A\n");
else printf("B\n");
}
else printf("C\n");
}
}
else
printf("No solution\n");
}
return 0;
}
/*
16 20
21
22
23
24
25
26
27
28
101
102
103
104
105
106
107
108
1 2
3 4
5 6
7 8
9 10
11 12
13 14
15 16
1 10
2 9
3 12
4 11
5 14
6 13
7 16
8 15
1 12
1 13
3 16
6 15
0 0
*/