• POJ 3648 2-sat


     题目大意:

    有一对新人结婚,邀请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 }
  • 相关阅读:
    IT常用英文术语解释发音
    大数据公司宣传语 公司文化企业文化
    vue 开发环境搭建,超级简单仅需3步。
    Mvc action间的传值
    获取文件路径
    WebStorm注册码
    webstrom快捷键
    Nuget-使用图形化界面打包自己的类库
    使用StyleCop进行代码审查
    InstallShield Limited Edition for Visual Studio 2013 图文教程(教你如何打包.NET程序)
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4682129.html
Copyright © 2020-2023  润新知