题意:
一对新人的婚礼...邀请了N-1对夫妇参加...现在所有人坐在长桌边..每个人可以做在长桌的某侧...但有限制...一对夫妇不能坐在同一侧..除了新娘..可能有些人之间有奸情...他们不能同时坐在新娘的对侧...请问有没有座次方案?如果有..请输出..
题解:
最开始做题目看错了!!看成通奸的人不能坐在一侧了...完全和题意无关..汗..后来发现样例不对...再看..再写...又发现新郎也可能通奸的....给跪....节操碎了...
要保证新娘对面侧的没有通奸的...反过来说..就是要保证新郎同侧的没有通奸的...这样就转化成了最基础的2-sat问题..细节注意..除了通过互斥关系做边...新娘应该做一条指向新郎的边..因为只是处理新郎一侧....最后的答案输出..记得反过来..因为求得是新郎侧..反过来才是新娘侧...
Program:
#include<iostream> #include<stdio.h> #include<cmath> #include<queue> #include<stack> #include<string.h> #include<map> #include<set> #include<algorithm> #define oo 1000000007 #define MAXN 200006 #define ll long long using namespace std; struct node { int x,y,next; }line[MAXN<<3]; int n,_next[MAXN],Lnum,dfn[MAXN],low[MAXN],tp[MAXN],DfsIndex,tpnum,color[MAXN]; stack<int> mystack; bool instack[MAXN]; void addline(int x,int y) { line[++Lnum].next=_next[x],_next[x]=Lnum; line[Lnum].x=x,line[Lnum].y=y; } void tarjan(int x) { int k,y; dfn[x]=low[x]=++DfsIndex; mystack.push(x); instack[x]=true; for (k=_next[x];k;k=line[k].next) { y=line[k].y; if (!dfn[y]) { tarjan(y); low[x]=min(low[x],low[y]); }else if (instack[y]) low[x]=min(low[x],dfn[y]); } if (dfn[x]==low[x]) { tpnum++; do { x=mystack.top(); mystack.pop(); instack[x]=false; tp[x]=tpnum; }while (low[x]!=dfn[x]); } } bool judge() { int i; for (i=0;i<n;i++) if (tp[i<<1]==tp[i<<1|1]) return false; return true; } void dfs(int x) { int k,i; color[x]=1; for (i=0;i<(n<<1);i++) if (tp[i]==x) color[tp[i^1]]=2; for (k=_next[x];k;k=line[k].next) if (!color[line[k].y]) dfs(line[k].y); } int main() { int m,i; while (~scanf("%d%d",&n,&m) && (n || m)) { memset(_next,0,sizeof(_next)); Lnum=0; while (m--) { int x,y; char c; scanf("%d%c",&x,&c); x<<=1; if (c=='h') x|=1; scanf("%d%c",&y,&c); y<<=1; if (c=='h') y|=1; addline(x,y^1); addline(y,x^1); } addline(0,1); memset(dfn,false,sizeof(dfn)); memset(instack,false,sizeof(instack)); while (!mystack.empty()) mystack.pop(); DfsIndex=tpnum=0; for (i=0;i<(n<<1);i++) if (!dfn[i]) tarjan(i); if (!judge()) { printf("bad luck\n"); continue; } int temp=Lnum; Lnum=0; memset(_next,false,sizeof(_next)); for (i=1;i<=temp;i++) { int x=tp[line[i].x],y=tp[line[i].y]; if (x==y) continue; addline(x,y); } memset(color,0,sizeof(color)); for (i=1;i<=tpnum;i++) if (!color[i]) dfs(i); for (i=2;i<(n<<1);i++) if (color[tp[i]]==1) { if (i>3) printf(" "); printf("%d",i>>1); if (i%2==0) printf("h"); else printf("w"); } printf("\n"); } return 0; }