uva 11294 2-SAT问题
来源:互联网 发布:显卡真假软件 编辑:程序博客网 时间:2024/05/22 16:49
英文太差了, 这个题目愣是半天没看懂 , 后面看别人翻译才看懂 , 英语是硬伤啊
题目大意:给 n 对夫妇安排座位 , 0h , 0w表示新郎新娘 , 新娘只能看到坐在她对面那一排的人 , 要求:
1、同一对新郎新娘不能做在同一侧
2、有m对人互为通奸(可以男男、女女、男女) , 新娘不能同时看到互为通奸的两个人。
注意:新郎也有可能和其他人通奸
做法:
1、分两种情况讨论 , 新娘在左侧 , 新娘在右侧 , 分别建图进行 2-SAT算法
2、不分左侧还是右侧 , 只分和新娘同侧或不同侧
下面给出做法一的代码
#include <iostream>#include <vector>#include <stdio.h>#include <string.h>using namespace std;#define maxn 200000int n , m;int a[maxn][2];vector<int>grap[maxn];bool mark[maxn];int s[maxn];int c;void init(){ memset(mark , 0 , sizeof(mark)); for(int i = 0; i < 4*n; i++) grap[i].clear();}void add_edge(int x , int y){ grap[x].push_back(y); //cout<<x<<",,"<<y<<endl;}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 < grap[u].size(); i++) { if(!dfs(grap[u][i])) return false; } return true;}bool slove(){ int i; for(i = 0; i < n*4; 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 print(int i){ int bz = true; for( ; i < 4*n ; i += 2) { if(i == 2*n || i == 2*n+1) continue; if(mark[i]) { if(i >= 2*n) { if(bz) printf("%dh" , (i-2*n)/2) , bz = false; else printf("% dh" , (i-2*n)/2); } else { if(bz) printf("%dw" , i/2) , bz = false; else printf("% dw" , i/2); } } } cout<<endl;}int main(){ while(scanf("%d %d" , &n , &m) != EOF) { if(n == 0 && m == 0) break; //n -= 1; init(); int i ; int x , y; char px , py; for(i = 0; i < m; i++) { scanf("%d%c %d%c" , &x , &px , &y , &py); //x -= 1; y -= 1; if(px == 'h') a[i][0] = 2*n+x*2; else a[i][0] = x*2; if(py == 'h') a[i][1] = 2*n+y*2; else a[i][1] = y*2; } for(i = 2; i < 2*n; i += 2) //夫妻之间 { add_edge(i , 2*n+i+1); add_edge(2*n+i+1,i ); add_edge(i+1 , 2*n+i); add_edge(2*n+i , i+1); } for(i = 0; i < m; i++) //仇人之间 { add_edge(a[i][0]+1 , a[i][1]); add_edge(a[i][1]+1 , a[i][0]); } mark[0] = mark[2*n+1] = true; bool bz = slove(); if(!bz) { init(); for(i = 0; i < 2*n; i += 2) //夫妻之间 { add_edge(i , 2*n+i+1); add_edge(2*n+i+1 ,i ); add_edge(i+1 , 2*n+i); add_edge(2*n+i , i+1); } for(i = 0; i < m; i++) //仇人之间 { add_edge(a[i][0] , a[i][1]+1); add_edge(a[i][1] , a[i][0]+1); } mark[1] = mark[2*n] = true; bz = slove(); if(!bz) printf("bad luck\n"); else { print(3); } } else { print(2); } } return 0;}
0 0
- uva 11294 2-SAT问题
- uva 11294 2-sat
- UVA - 11294 Wedding(2-SAT)
- Uva 11294 Wedding(2-SAT)
- UVA 11294 Wedding(2-sat)
- UVA 1146 飞机调度 2-SAT问题
- UVa 11294 - Wedding(2-SAT)
- uva 11294 - Wedding(2 sat)
- UVA 1146 2-SAT
- UVA 1391 2-SAT
- UVA 1146 Now or later(2-SAT问题)
- UVA Live 3211飞机调度问题-二分+2-SAT
- UVA 1391 Astronauts 2-sat
- uva 3713 Astronauts (2-sat)
- (beginer)DFS (2-SAT) UVA 11294 Wedding
- 【2-SAT】2sat问题小结
- 2-SAT问题
- 2-SAT 问题
- Bat学习笔记
- POJ 1741 Tree
- 使用R完成字符串的子字符串频率统计
- 初学Java,文档注释(二)
- undefined reference to 'htons' Android NDK错误
- uva 11294 2-SAT问题
- UVa 11729 Commando War
- 一些求数据库对象的SQL语句
- TiledMap 使用
- C/C++格式化字符串说明
- Android中关于Volley的使用(十)对Request和Reponse的认识
- 从计算的本质到编程语言
- 其他三次 只出现一次的数
- 定长单元的批次内存缓存池的简洁实现