POJ 3648 Wedding

Posted MSPqwq

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 3648 Wedding相关的知识,希望对你有一定的参考价值。

经典2-sat

题解:

把一对夫妻视为一个集合,按淫乱关系建边

如果有淫乱关系显然不能都坐在新娘对面

注意要给(1,1+n)连边保证必须新娘和新郎坐对桌

tarjan缩完点之后,因为tarjan的编号是拓扑的逆序,所以我们在选择坐在新娘对面的人的时候,只要保证选择w和h编号较小的即可

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<stack>
 5 #define N 2010
 6 using namespace std;
 7 int n,m,ecnt,dfn[N],low[N],indx,head[N],belong[N],cnt,inst[N],t,ok;
 8 char a,b;
 9 stack <int> st;
10 struct edge
11 {
12     int u,v,nxt;
13 }e[N*N];
14 int get(int x)
15 {
16     return (x<=n)?x+n:x-n;
17 }
18 void add(int u,int v)
19 {
20     e[++ecnt].v=v;
21     e[ecnt].u=u;
22     e[ecnt].nxt=head[u];
23     head[u]=ecnt;
24 }
25 void tar(int u)
26 {
27     dfn[u]=low[u]=++indx;
28     inst[u]=1;
29     st.push(u);
30     for (int i=head[u];i;i=e[i].nxt)
31     {
32         int v=e[i].v;
33         if (!dfn[v])
34         {
35             tar(v);
36             low[u]=min(low[u],low[v]);
37         }
38         else if (inst[v]==1) 
39             low[u]=min(low[u],dfn[v]);
40     }
41     if (dfn[u]==low[u])
42     {
43         ++cnt;
44         while (1)
45         {
46             t=st.top();
47             belong[t]=cnt;
48             st.pop();
49             inst[t]=0;
50             if (t==u)
51                 break;
52         }    
53     }
54 }
55 void init()
56 {
57     cnt=0;
58     memset(dfn,0,sizeof(dfn));
59     ecnt=0;
60     memset(head,0,sizeof(head));
61     memset(low,0,sizeof(low));
62     memset(inst,0,sizeof(inst));
63     memset(belong,0,sizeof(belong));
64     indx=0;
65     ok=1;
66 }
67 int main()
68 {
69     while (scanf("%d%d",&n,&m)!=EOF )
70     {
71         if (n+m==0) break;
72         init();
73         int u,v;
74         for (int i=1;i<=m;i++)
75         {
76             scanf("%d%c %d%c",&u,&a,&v,&b);
77             u++,v++;
78             if (a==h) u+=n;
79             if (b==h) v+=n;
80             add(u,get(v));
81             add(v,get(u));
82         }
83         add(1,1+n);
84         for (int i=1;i<=2*n;i++)
85             if (!dfn[i]) tar(i);
86         for (int i=1;i<=n && ok==1;i++)
87             if (belong[i]==belong[i+n]) 
88                 ok=0; 
89         if (!ok)
90         {
91             puts("bad luck");
92             continue;
93         }
94         for (int i=2;i<=n;i++)
95             printf("%d%c%c",i-1,(belong[i]>belong[i+n])?w:h," \n"[i==n]);
96         if (n<2) printf("\n");
97     }
98     return 0;
99 }

 

以上是关于POJ 3648 Wedding的主要内容,如果未能解决你的问题,请参考以下文章

poj 3648 Wedding 2-SAT问题入门题目

POJ 3648 Wedding

Wedding (poj 3648 2-SAT 输出随意一组解)

poj3648:Wedding——题解(配2-SAT简易讲解)

POJ 3648-Wedding(2-SAT)

UVA11450 Wedding shoppingDP