首页 > 其他 > 详细

POJ 3648 Wedding

时间:2017-11-18 10:38:41      阅读:309      评论:0      收藏:0      [点我收藏+]

经典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

原文:http://www.cnblogs.com/mrsheep/p/7855987.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!