POJ 3648 2-SAT
来源:互联网 发布:手机能不能做淘宝客服 编辑:程序博客网 时间:2024/06/18 13:34
POJ 3648
题目链接:
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=17198
题意:
n对夫妇,其中0号夫妇为新婚夫妇。新娘由于带着婚纱只能看到对面的人。
现在安排座位,座位的规则是不坐左边就坐右边。要求一对夫妇不能同时坐一边,而且一些有特殊关系的人不能坐在新娘的的对面。
输出可能坐在新娘这边的夫或者妇,按编号顺序输出。
思路:
2-SAT版,当然要重新编辑一下。
首先bride是新娘而不是新郎。
设坐在新娘这边而TRUE,坐对面为FALSE。剩下任务就是套版。
源码:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <queue>
#include <vector>
#include <stack>
using namespace std;
const int MAXN = 1000 + 5;
vector<int>lin[MAXN];
stack<int>sta;
int valid[MAXN];
char str[10];
int n, m;
//int cal()
//{
// int len = strlen(str);
// int ans = 0;
// for(int i = 0 ; i < len - 1 ; i++)
// ans = ans * 10 + str[i] - '0';
// ans = ans * 2;
// if(str[len - 1] == 'w')
// ans += 1;
// return ans;
//}
bool dfs(int u)
{
// printf("u = %d\n", u);
if(valid[u^1]) return false;
if(valid[u]) return true;
valid[u] = true;
sta.push(u);
for(int i = 0 ; i < (int)lin[u].size() ; i++){
int v = lin[u][i];
// printf("v = %d\n\n", v);
if(!dfs(v)) return false;
}
return true;
}
bool ok()
{
while(!sta.empty()) sta.pop();
memset(valid, false, sizeof(valid));
for(int i = 0 ; i < 2 * n ; i+=2){
if(!valid[i] && !valid[i^1]){
// printf("i = %d\n", i);
if(i == 0){
if(!dfs(1)) return false;
}
else{
if(!dfs(i)){
// printf("i = %d\n", i);
while(!sta.empty()){
int org = sta.top(); sta.pop();
valid[org] = false;
if(org == i)
break;
}
if(!dfs(i^1)) return false;
}
}
}
}
return true;
}
int main()
{
while(scanf("%d%d", &n, &m) != EOF && n + m){
for(int i = 0 ; i < 2 * n ; i++)
lin[i].clear();
int u, v;
getchar();
for(int i = 1 ; i <= m ; i++){
int flag = 0;
int u, v;
char op1, op2;
scanf("%d%c %d%c", &u, &op1, &v, &op2);
u *= 2, v *= 2;
if(op1 == 'w') u += 1;
if(op2 == 'w') v += 1;
// printf("u = %d, v = %d\n", u, v);
// printf("u^1 = %d, v^1 = %d\n", u ^ 1, v ^ 1);
lin[u^1].push_back(v);
lin[v^1].push_back(u);
}
// for(int i = 0 ; i < 2 * n ; i++){
// printf("i = %d, j = ", i);
// for(int j = 0 ; j < (int)lin[i].size() ; j++)
// printf("%d ", lin[i][j]);
// printf("\n");
// }
memset(valid, false, sizeof(valid));
if(ok()){
int f = 1;
for(int i = 2 ; i < 2 * n ; i += 2){
if(f) f = 0;
else printf(" ");
printf("%d", i / 2);
if(valid[i]) printf("h");
else printf("w");
}
printf("\n");
}
else
printf("bad luck\n");
}
return 0;
}
版版~:
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <string>
#include <queue>
#include <stack>
#include <vector>
using namespace std;
const int MAXN = 1005;
struct TwoSAT
{
int n;
vector<int> G[MAXN * 2];
bool valid[MAXN * 2];
int S[MAXN * 2], c;
bool dfs(int x)
{
if(valid[x ^ 1]) return false;
if(valid[x]) return true;
valid[x] = true;
S[c++] = x;
for(int i = 0 ; i < (int)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(valid, false, sizeof(valid));
}
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(!valid[i] && !valid[i^1]){
c = 0;
if(i > 0){
if(!dfs(i)){
while(c > 0) valid[S[--c]] = false;
if(!dfs(i + 1)) return false;
}
}
else{
if(!dfs(i)) return false;
}
}
}
return true;
}
};
int main()
{
int n, m;
while(scanf("%d%d", &n, &m) != EOF && n + m){
TwoSAT lv;
lv.init(n);
int u, v;
char op1, op2;
for(int i = 1 ; i <= m ; i++){
scanf("%d%c %d%c", &u, &op1, &v, &op2);
int uval = op1 == 'w' ? 0 : 1;
int vval = op2 == 'w' ? 0 : 1;
lv.add_clause(u, uval, v, vval);
}
if(lv.solve()){
int f = 1;
for(int i = 2 ; i < 2 * n ; i+=2){
if(f) f = 0;
else printf(" ");
printf("%d", i/2);
if(lv.valid[i]) printf("w");
else printf("h");
}
printf("\n");
}
else
printf("bad luck\n");
}
return 0;
}
- 【2-SAT】POJ 3648
- POJ 3648 2-SAT
- poj 3648 Wedding 2sat
- poj 3648 Wedding 2-SAT
- 2-sat->poj 3648 Wedding
- POJ 3648 Wedding(2-SAT)
- 【POJ】3648 Wedding 2-sat
- POJ-3648(2-SAT)
- poj 3648 Wedding 2-sat
- POJ 3648 Wedding 2-SAT
- poj 3648 2-SAT算法
- POJ 3648Wedding 2-sat
- |poj 3648|2-SAT|Wedding
- POJ 3648 2-sat 输出解
- POJ 3648 Wedding(2-SAT)
- POJ 3648 Wedding(2-SAT+输出方案)
- POJ 3648 2SAT求解方案
- poj 3648 2-sat输出一组解
- Linux C中的opendir()
- 1095. Cars on Campus (30)
- LintCode-删除排序数组中的重复数字
- C# 窗体 webbrowser 窗体调用javascript方法 实例
- Ubuntu下开启SSH服务
- POJ 3648 2-SAT
- leetcode--LinkedListCycleII
- js获取下拉框属性值的写法
- linux 定时调度 的 工具
- python requests encoding
- thinkphp 更新和插入记录
- Android.mk文件语法规范——深入了解android平台的jni
- Cocoapods安装遇到的问题
- POJ 2455--Secret Milking Machine【二分枚举 && 最大流 && 经典】