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的主要内容,如果未能解决你的问题,请参考以下文章
Wedding (poj 3648 2-SAT 输出随意一组解)