/*
2SAT,找出一组解
逆缩图序,拓扑排序,然后染色。
找出和新娘颜色相同的点
*/// include file
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>
#include <ctime>#include <iostream>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <bitset>
#include <strstream>#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <list>
#include <functional>using namespace std;// typedef
typedef long long LL;
typedef unsigned long long ULL;//
#define read freopen("in.txt","r",stdin)
#define write freopen("out.txt","w",stdout)
#define FORi(a,b,c) for(int i=(a);i<(b);i+=c)
#define FORj(a,b,c) for(int j=(a);j<(b);j+=c)#define FF(i,a) for(int i=0;i<(a);i+++)
#define FFD(i,a) for(int i=(a)-1;i>=0;i--)
#define Z(a) (a<<1)
#define Y(a) (a>>1)const double eps = 1e-11;
const double Pi = acos(-1.0);template<class T> inline T sqr(T a){return a*a;}
template<class T> inline T TMAX(T x,T y)
{if(x>y) return x;return y;
}
template<class T> inline T TMIN(T x,T y)
{if(x<y) return x;return y;
}
template<class T> inline void SWAP(T &x,T &y)
{T t = x;x = y;y = t;
}
template<class T> inline T MMAX(T x,T y,T z)
{return TMAX(TMAX(x,y),z);
}// code begin
#define MAXN 200vector<int> G[MAXN];
int NG[MAXN][MAXN];
int in[MAXN];
int col[MAXN];
vector<int> tp;
int link[MAXN];int scc;
int cnt;
int used[MAXN];
int stk1[MAXN],top1;
int stk2[MAXN],top2;
int isin[MAXN];
int dfn[MAXN];
int low[MAXN];
int id[MAXN];
int N,M;void gabow_scc(int i)
{used[i] = true;stk1[top1++] = i;stk2[top2++] = i;dfn[i] = cnt++;isin[i] = true;FORj( 0,G[i].size(),1 ){if(!used[ G[i][j] ]){gabow_scc(G[i][j]);}else if(isin[G[i][j]]){while(dfn[stk2[top2-1]]>dfn[G[i][j]])top2--;}}if(i==stk2[top2-1]){top2--;int w;do{w = stk1[--top1];isin[w] = false;id[w] = scc;}while(w!=i);scc++;}
}void tarjan_scc(int i)
{used[i] = true;stk1[top1++] = i;dfn[i] = cnt;low[i] = cnt;cnt++;isin[i] = true;FORj(0,G[i].size(),1){if(!used[ G[i][j] ]){tarjan_scc(G[i][j]);low[i] = TMIN(low[i],low[G[i][j]]);}else if(isin[G[i][j]]){low[i] = TMIN(low[i],dfn[G[i][j]]);}}if(dfn[i]==low[i]){int w;do{w=stk1[--top1];isin[w] = false;id[w] = scc;}while(w!=i);scc++;}
}void dfs(int i)
{FORj(1,scc,1){if( !col[j]&&NG[i][j] ){col[j]=2;dfs(j);}}
}int getnum(char *ta)
{int n = strlen(ta);if(n==3){return 2*( (ta[0]-'0')*10+ta[1]-'0' )+(ta[2]=='w'?0:1);}return 2*(ta[0]-'0')+(ta[1]=='w'?0:1);
}int main()
{read;write;while(scanf("%d %d",&N,&M)!=-1){if(N+M==0) break;FORi(0,N*4,1){G[i].clear();}// 新娘和新郎有限制条件G[2*0+1].push_back(2*0);G[2*1].push_back(2*1+1);FORi(2,N*2,2){// A xor B = 1;// i i+1G[2*i].push_back(2*(i+1)+1);G[2*(i+1)].push_back(2*i+1);G[2*(i+1)+1].push_back(2*i);G[2*i+1].push_back(2*(i+1));}// 通奸关系char s1[5],s3[5];while(M--){scanf("%s %s",s1,s3);// 不能是1 1 int a = getnum(s1);int b = getnum(s3);if(a>b) SWAP(a,b);//printf("%d %d\n",a,b);if(a>1&&b>1){G[2*a+1].push_back(2*b);G[2*b+1].push_back(2*a);}else if(a==1&&b>1){G[2*b+1].push_back(2*b);}else if(a==0&&b>1){//G[2*b+1].push_back(2*b);}}//memset(used,0,sizeof(used));memset(dfn,0,sizeof(dfn));memset(low,0,sizeof(low));memset(id,0,sizeof(id));scc = 1;cnt = 1;top1 = 0;FORi(0,4*N,1){if(!used[i]){tarjan_scc(i);}}bool f = true;FORi(0,2*N,1){if(id[2*i]==id[2*i+1]){f=false;break;}}if(f){// 找一组方案FORi(1,scc,1){FORj(1,scc,1)NG[i][j]=0;}memset(in,0,sizeof(in));FORi(0,4*N,1){FORj(0,G[i].size(),1){if( id[i]!=id[G[i][j]] ){NG[ id[G[i][j]] ][ id[i] ] = 1;}}}FORi(0,2*N,2){//i i+1link[id[2*i]] = id[2*i+1];link[id[2*i+1]] = id[2*i];link[id[2*(i+1)]] = id[2*(i+1)+1];link[id[2*(i+1)+1]] = id[2*(i+1)];}//新图为NGtp.clear();queue<int> qi;FORi(1,scc,1){FORj(1,scc,1){if(i!=j && NG[i][j]){in[j]++;}}}FORi(1,scc,1){if(in[i]==0){qi.push(i);}}while(!qi.empty()){int cur = qi.front();qi.pop();tp.push_back(cur);FORi(1,scc,1){if(cur!=i && NG[cur][i]){in[i]--;if(in[i]==0)qi.push(i);}}}//printf("scc:%d tp:%d\n",scc,tp.size());// 排序后memset(col,0,sizeof(col));FORi(0,tp.size(),1){if(!col[tp[i]]){col[tp[i]]=1;//对立面col[link[tp[i]]] = 2;// 子孙dfs(link[tp[i]]);}}// 所有染的点就是一组解FORi(2,2*N,2){//i i+1//printf("颜色:[%d,%d] %d %d\n",i/2,(i+1)/2,col[id[2*i]],col[id[2*(i+1)]]);if(i!=2) printf(" ");if( col[id[2*i]]==col[id[2*0]]) printf("%d%c",i/2,(i&1)?'h':'w');if( col[id[2*(i+1)]]==col[id[2*0]]) printf("%d%c",(i+1)/2,((i+1)&1)?'h':'w');}printf("\n");}elseprintf("bad luck\n");}return 0;
}
转载于:https://www.cnblogs.com/ac2012/archive/2011/03/01/1968100.html