POJ-3648-Wedding(2-sat)
2013-01-31 01:05
363 查看
POJ 2-sat 六题之四
http://blog.sina.com.cn/s/blog_64675f540100k1g9.html
题目描述:
一堆夫妇去参加一对新人的婚礼。人们坐在一个很长很长的桌子的两侧(面对面)。新郎新娘在桌子头面对面座。
新娘不希望看见她对面的一排有一对夫妇坐着(夫妇需要分开两排座)。
同时,一些人之间有暧昧关系,新娘也不希望有暧昧关系的人同时坐在她对面的一排。
问你可否满足新娘的要求,可以的话,输出一种方案。
解题报告:
首先,每个人都可能坐在桌子两侧的某一侧,这样,把每个人拆成两个点。
第一个点表示桌子左侧(我自己定义的),第二个表示右侧。即i和i’
新娘我让她坐在左侧,新郎坐在右侧。
新娘编号0,加入边i’-》i,就是说如果新娘坐右侧的话,就需要坐到左侧(这样就限定了新娘坐在左侧),新郎同样处理。
夫妇一定一左侧,一右侧。
有暧昧关系的人要么同时坐在左侧(不让新娘看见),要么一个坐在左侧,一个坐在右侧。
http://blog.sina.com.cn/s/blog_64675f540100k1g9.html
题目描述:
一堆夫妇去参加一对新人的婚礼。人们坐在一个很长很长的桌子的两侧(面对面)。新郎新娘在桌子头面对面座。
新娘不希望看见她对面的一排有一对夫妇坐着(夫妇需要分开两排座)。
同时,一些人之间有暧昧关系,新娘也不希望有暧昧关系的人同时坐在她对面的一排。
问你可否满足新娘的要求,可以的话,输出一种方案。
解题报告:
首先,每个人都可能坐在桌子两侧的某一侧,这样,把每个人拆成两个点。
第一个点表示桌子左侧(我自己定义的),第二个表示右侧。即i和i’
新娘我让她坐在左侧,新郎坐在右侧。
新娘编号0,加入边i’-》i,就是说如果新娘坐右侧的话,就需要坐到左侧(这样就限定了新娘坐在左侧),新郎同样处理。
夫妇一定一左侧,一右侧。
有暧昧关系的人要么同时坐在左侧(不让新娘看见),要么一个坐在左侧,一个坐在右侧。
// File Name: 3648.cpp // Author: zlbing // Created Time: 2013/1/31 0:06:20 #include<iostream> #include<string> #include<algorithm> #include<cstdlib> #include<cstdio> #include<set> #include<map> #include<vector> #include<cstring> #include<stack> using namespace std; #define MAXN 200 struct TwoSAT{ int n; vector<int>G[MAXN*2]; bool mark[MAXN*2]; stack<int>S; bool dfs(int x) { if(mark[x^1])return false; if(mark[x])return true; mark[x]=true; S.push(x); for(int i=0;i<G[x].size();i++) { int v=G[x][i]; if(!dfs(v))return false; } return true; } void init(int _n) { n=_n; for(int i=0;i<2*n;i++) G[i].clear(); memset(mark,0,sizeof(mark)); } /* 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); } */ void add_clause(int x,int y) { G[x].push_back(y); } bool solve() { for(int i=0;i<2*n;i=i+2) { if(!mark[i]&&!mark[i+1]){ while(!S.empty()) { S.pop(); } if(!dfs(i)) { while(!S.empty()) { mark[S.top()]=false; S.pop(); } if(!dfs(i+1))return false; } } } char e; bool first=true; for(int i=4;i<4*n;i++) if(mark[i]){ int k=i/4; if(i%4<2)e='w'; else e='h'; if(i%2==0){ if(first){ printf("%d%c",k,e); first=false; }else printf(" %d%c",k,e); } } printf("\n"); return true; } }; TwoSAT solver; int main(){ int n,m; while(~scanf("%d%d",&n,&m)) { solver.init(2*n); if(n==0&&m==0) break; int a,b; char cha,chb; solver.add_clause(1,0); solver.add_clause(2,3); for(int i=1;i<n;i++) { a=i*2,b=i*2+1; solver.add_clause(a*2,b*2+1); solver.add_clause(b*2+1,a*2); solver.add_clause(a*2+1,b*2); solver.add_clause(b*2,a*2+1); } for(int i=0;i<m;i++) { scanf("%d%c %d%c",&a,&cha,&b,&chb); a=cha=='w'?a*2:a*2+1; b=chb=='w'?b*2:b*2+1; solver.add_clause(a*2+1,b*2); solver.add_clause(b*2+1,a*2); } if(!solver.solve()) printf("bad luck\n"); } return 0; }
相关文章推荐
- poj 3648 Wedding(2-SAT)
- POJ 3648 Wedding[2-SAT]
- poj 3648 Wedding 2-SAT
- POJ 3648 Wedding 2-sat输出一组解
- POJ 3648 Wedding(2-SAT)
- |poj 3648|2-SAT|Wedding
- Poj 3648 Wedding (2-sat 输出方案)
- poj 3648 Wedding 2-SAT
- 【POJ】3648 Wedding 2-sat
- POJ 3648 Wedding(2-SAT)
- POJ 3648 Wedding(2-SAT)
- POJ 3648 Wedding (2-SAT,经典)
- poj 3648 Wedding 【2-sat 经典建图 输出一组可行解 好题】 【tarjan求SCC + 缩点 + 拓扑排序 + 染色】
- poj 3648 Wedding 2-sat
- POJ_3648 Wedding 2-Sat
- POJ 3648-Wedding(2-SAT)
- Wedding (poj 3648 2-SAT 输出任意一组解)
- poj 3648 Wedding(2-sat 求解)
- POJ 3648 Wedding(2-SAT 拓扑排序输出任意一种解决方案)
- POJ 3648 Wedding (2-SAT+输出可行解)