2-STA求解问题,2-SAT最重要的就是如果a与b矛盾,就加边a—>b',
因为新娘不能看到有不正当关系的两人,所以只需要在每对夫妇中选一个坐在新娘对面,
他们之间没有关系不正当的人。
#include<stdio.h> #include<string.h> #include<queue> #include<stack> #define N 500 using namespace std; int n,m,low[N],dfs[N],ins[N],belong[N],link[N]; int ans,idx,first[N],first1[N],num,num1,cf[N],color[N],indeg[N]; struct eage { int ed,next; }E[N*N],E1[N*N]; void addeage(int x,int y) { E[num].ed=y; E[num].next=first[x]; first[x]=num++; } void addeage1(int x,int y) { E1[num1].ed=y; E1[num1].next=first1[x]; first1[x]=num1++; } void insit() { memset(color,0,sizeof(color)); memset(dfs,-1,sizeof(dfs)); memset(ins,0,sizeof(ins)); memset(first,-1,sizeof(first)); memset(indeg,0,sizeof(indeg)); memset(first1,-1,sizeof(first1)); memset(link,0,sizeof(link)); num=ans=idx=0;num1=0; } stack<int>Q; void Tarjan(int x) { int p,v; low[x]=dfs[x]=idx++; ins[x]=1; Q.push(x); for(p=first[x];p!=-1;p=E[p].next) { v=E[p].ed; if(dfs[v]==-1) { Tarjan(v); low[x]=low[x]>low[v]?low[v]:low[x]; } else if(ins[v]==1) { low[x]=low[x]>dfs[v]?dfs[v]:low[x]; } } if(dfs[x]==low[x]) { do { v=Q.top(); Q.pop(); ins[v]=0; belong[v]=ans; }while(v!=x); ans++; } } void topsort() { queue<int>QQ; int i,v,p,q; for(i=0;i<ans;i++) if(indeg[i]==0) QQ.push(i); while(!QQ.empty()) { v=QQ.front(); QQ.pop(); if(color[v]==0) { color[v]=1; color[cf[v]]=-1; } for(p=first1[v];p!=-1;p=E1[p].next) { q=E1[p].ed; indeg[q]--; if(indeg[q]==0) QQ.push(q); } } } void solvd() { int i,v; for(i=0;i<2*n;i++) { for(int p=first[i];p!=-1;p=E[p].next) { v=E[p].ed; if(belong[i]!=belong[v]) { addeage1(belong[v],belong[i]); indeg[belong[i]]++; } } } topsort(); for(i=0;i<n;i++) { if(color[belong[i]]==1) link[i]=1; } for(i=1;i<n;i++) { if(link[i]==1) printf("%dh ",i); else printf("%dw ",i); } printf("\n"); } int main() { int i,x,x1,y,y1; char ch1,ch2; while(scanf("%d%d",&n,&m),n||m) { insit(); for(i=0;i<m;i++) { scanf("%d%c %d%c",&x,&ch1,&y,&ch2); if(ch1=='h') x1=x,x+=n; else x1=x+n; if(ch2=='h') y1=y,y+=n; else y1=y+n; addeage(x,y1); addeage(y,x1); } addeage(0,n); for(i=0;i<n*2;i++) { if(dfs[i]==-1) Tarjan(i); } for(i=0;i<n;i++) { if(belong[i]==belong[i+n]) break; cf[belong[i]]=belong[i+n]; cf[belong[i+n]]=belong[i]; } if(i==n) solvd(); else printf("bad luck\n"); } return 0; }