码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 3648 2-sat

时间:2015-07-28 12:32:25      阅读:95      评论:0      收藏:0      [点我收藏+]

标签:

 题目大意:

有一对新人结婚,邀请n对夫妇去参加婚礼。
有一张很长的桌子,人只能坐在桌子的两边,还要满
足下面的要求:1.每对夫妇不能坐在同一侧 2.n对夫妇
之中可能有通奸关系(包括男男,男女,女女),有通
奸关系的不能同时坐在新娘的对面,可以分开坐,可以
同时坐在新娘这一侧。如果存在一种可行的方案,输出
与新娘同侧的人。

这里因为输入的是字符串,要注意的是数字可能不只是一个个位数,要

while(isdigit(s1[index1])) i = i*10+(s1[index1++]-‘0‘);
while(isdigit(s2[index2])) j = j*10+(s2[index2++]-‘0‘);

这里自己一直没找到原因,错了很多次

 

其他的就按照 2i 表示 i 号丈夫坐在新娘对面,2i+1 表示i 号妻子坐在新娘对面

初始将新郎对应的编号的标记设为true , 因为他必然坐在新娘对面

这样找下来,最后标记为false的便是坐在新娘这边的

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <vector>
 4 #include <ctype.h>
 5 #include <algorithm>
 6 using namespace std;
 7 #define N 300
 8 int n , m , S[N] , c ;
 9 bool mark[N];
10 char s1[10] , s2[10];
11 vector<int> G[N];
12 
13 void init()
14 {
15     memset(mark , 0 , sizeof(mark));
16     for(int i=0 ; i<n*2 ; i++) G[i].clear();
17 }
18 
19 bool dfs(int u)
20 {
21     if(mark[u]) return true;
22     if(mark[u^1]) return false;
23     mark[u] = true;
24     S[c++] = u;
25     for(int i=0 ; i<G[u].size() ; i++)
26         if(!dfs(G[u][i])) return false;
27     return true;
28 }
29 
30 bool solve()
31 {
32     mark[0] = true;//一定是坐在新娘对面,所以新郎为true
33     for(int i=0 ; i<2*n ; i+=2){
34         if(!mark[i] && !mark[i^1]){
35             c = 0;
36             if(!dfs(i)){
37                 while(c) mark[S[--c]] = false;
38                 if(!dfs(i^1)) return false;
39             }
40         }
41     }
42     return true;
43 }
44 
45 void add_clause(int i , int p , int j , int q)
46 {
47     int m = 2*i+p , n = 2*j+q;
48     G[m].push_back(n^1);
49     G[n].push_back(m^1);
50 }
51 
52 int main()
53 {
54    // freopen("in.txt" , "r" , stdin);
55     while(scanf("%d%d" , &n , &m) , n+m)
56     {
57         init();
58         while(m--){
59             scanf("%s%s" , s1 , s2);
60             int i , j , p , q;
61             i = 0 , j = 0;
62             int index1 = 0 , index2 = 0;
63             while(isdigit(s1[index1])) i = i*10+(s1[index1++]-0);
64             while(isdigit(s2[index2])) j = j*10+(s2[index2++]-0);
65             p = s1[index1]==h?0:1 , q = s2[index2]==h?0:1;
66             add_clause(i , p , j ,q);
67         }
68         if(!solve()) puts("bad luck");
69         else{
70             int flag = 0;
71             for(int i=2 ; i<n*2 ; i++){
72                 if(!mark[i]){
73                     if(flag) printf(" %d%c" , i/2 , i&1?w:h);
74                     else printf("%d%c" , i/2 , i&1?w:h);
75                     flag=1;
76                 }
77             }
78             puts("");
79         }
80     }
81     return 0;
82 }

 

POJ 3648 2-sat

标签:

原文地址:http://www.cnblogs.com/CSU3901130321/p/4682129.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!