• 【UVA11294】Wedding (2-SAT)


    题意:

      有N-1对夫妻参加一个婚宴,所有人都坐在一个长长的餐桌左侧或者右侧,新郎和新娘面做面坐在桌子的两侧。由于新娘的头饰很复杂,她无法看到和她坐在同一侧餐桌的人,只能看到对面餐桌的人。任意一对夫妻不能坐在桌子的同侧,另外有m对人吵过架,而新娘不希望看到两个吵过架的人坐在他的对面,问如何安排这些座位。

    分析:

      考虑新娘对面那一边,吵过架的不能坐在一起。两夫妻中只能选一个而且必须选一个坐在新娘对面,但不能选两个吵过架的人。所以我们可以用人物关系建图,然后用2-SAT求解。

      另外,说一下2-SAT的不回溯算法,是在图对称的时候才保证正确性的。所以记得保证图是对称的哦。

    代码如下:

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<algorithm>
     6 using namespace std;
     7 #define Maxn 2010
     8 #define Maxm 1000010
     9 
    10 int n,m;
    11 int first[Maxn];
    12 bool mark[Maxn];
    13 int s[Maxn],sl;
    14 
    15 struct node
    16 {
    17     int x,y,next;
    18 }t[Maxm];int len;
    19 
    20 void ins(int x,int y)
    21 {
    22     t[++len].x=x;t[len].y=y;
    23     t[len].next=first[x];first[x]=len;
    24 }
    25 
    26 bool dfs(int x)
    27 {
    28     if(mark[x^1]) return 0;
    29     if(mark[x]) return 1;
    30     mark[x]=1;
    31     s[++sl]=x;
    32     for(int i=first[x];i;i=t[i].next)
    33     {
    34         if(!dfs(t[i].y)) return 0;
    35     }
    36     return 1;
    37 }
    38 
    39 bool ffind()
    40 {
    41     memset(mark,0,sizeof(mark));
    42     mark[0]=1;
    43     if(!dfs(0)) return 0;
    44     for(int i=1;i<n;i++)
    45     {
    46         if(mark[i*2]||mark[i*2+1]) continue;
    47         sl=0;
    48         if(!dfs(i*2))
    49         {
    50             while(sl) mark[s[sl--]]=0;
    51             if(!dfs(i*2+1)) return 0;
    52         }
    53     }
    54     return 1;
    55 }
    56 
    57 int main()
    58 {
    59     while(1)
    60     {
    61         scanf("%d%d",&n,&m);
    62         if(n==0&&m==0) break;
    63         getchar();len=0;
    64         memset(first,0,sizeof(first));
    65         bool p;
    66         for(int i=1;i<=m;i++)
    67         {
    68             int x,y,p1,p2;
    69             char c;
    70             scanf("%d%c",&x,&c);getchar();
    71             p1=(c=='h'?0:1);
    72             scanf("%d%c",&y,&c);//getchar();
    73             p2=(c=='h'?0:1);
    74             getchar();
    75             if(p1==0&&p2==0) p=1;
    76             ins(x*2+p1,y*2+1-p2);//ins(y*2+1-p2,x*2+p1);
    77             ins(y*2+p2,x*2+1-p1);//ins(x*2+1-p1,y*2+p2);
    78         }
    79         if(!ffind()) printf("bad luck
    ");
    80         else
    81         {
    82             for(int i=1;i<n;i++)
    83             {
    84                 if(i!=1) printf(" ");
    85                 if(mark[i*2]) printf("%dw",i);
    86                 else printf("%dh",i);
    87             }
    88         }printf("
    ");
    89     }
    90     return 0;
    91 }
    [uva11294]

    2016-03-24 13:24:20

  • 相关阅读:
    JS中数字和字符相加相减问题
    学习JQGRID
    认识三层架构
    log4net.dll
    UML统一建模语言
    纳税服务系统【条件查询数据回显、分页】
    纳税服务系统【抽取BaseService、条件查询】
    Jquery总结图
    Hibernate逆向工程【PowerDesigner、idea环境下】
    纳税服务系统【信息发布管理、Ueditor、异步信息交互】
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/5315122.html
Copyright © 2020-2023  润新知