可以把一对夫妇当成一个节点,然后拆点的话,h和w分别为真和假,然后直接按照题目中说的建图染色即可
#include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <queue> #include <algorithm> using namespace std; const int maxn = 100; const int maxm = 1000; struct node{ int v,next; }edge[maxm]; int res[maxm][2],head[maxn],low[maxn],dfn[maxn],stack[maxn],in[maxn],fa[maxn],ha[maxn]; int color[maxn]; int n,m,Time,top,scc_cnt,id; vector<int>DAG[maxn]; queue<int>que; void add_edge(int u,int v){ edge[id].v = v;edge[id].next = head[u]; head[u] = id++; } void init(){ memset(head,-1,sizeof(head)); memset(in,0,sizeof(in)); memset(dfn,0,sizeof(dfn)); memset(fa,0,sizeof(fa)); id = 0; int i; int u,v; char ch1,ch2; for(i = 0; i < m; i++){ scanf("%d%c %d%c",&u,&ch1,&v,&ch2); u <<= 1;v <<= 1; if(ch1 == 'w')u ^= 1; if(ch2 == 'w')v ^= 1; //必须在一起的连边 add_edge(u^1,v); add_edge(v^1,u); } //这条边必须要加 add_edge(0,1); } int min(int x,int y){ return x < y ? x : y; } void tarjan(int u){//求强连通分量并缩点 dfn[u] = low[u] = ++Time; stack[top++] = u;in[u] = 1; for(int id = head[u]; id != -1; id = edge[id].next){ int v = edge[id].v; if(!dfn[v]){ tarjan(v); low[u] = min(low[v],low[u]); } else if(in[v])low[u] = min(low[u],dfn[v]); } if( dfn[u] == low[u]){ scc_cnt++; do{ int v = stack[--top]; fa[v] = scc_cnt; in[v] = 0; }while(u != stack[top]); } } void topsort(){//拓扑排序并着色 memset(color,0,sizeof(color)); while(!que.empty()){ int u = que.front(); que.pop(); if(!color[u])color[u] = 1,color[ha[u]] = 2; for(int i = 0; i < DAG[u].size(); i++){ int v = DAG[u][i]; in[v]--; if(!in[v])que.push(v); } } } int main(){ // freopen("in.txt","r",stdin); while(~scanf("%d%d",&n,&m),n||m){ init(); Time = top = scc_cnt = 0; int i; for( i = 0; i < 2*n; i++) if(!dfn[i])tarjan(i); for(i = 0; i < n; i ++)//夫妻不能做在同一边 if(fa[i*2] == fa[i*2+1])break; else { ha[fa[i*2]] = fa[i*2+1];ha[fa[i*2+1]] = fa[i*2]; } if( i < n){ puts("bad luck"); continue; } memset(in,0,sizeof(in)); for( i = 1; i <= scc_cnt; i++)DAG[i].clear(); //建反序拓扑图 for(int u = 0; u < n*2; u++){ for( id = head[u] ; id != -1; id = edge[id].next){ int v = edge[id].v; if( fa[u] != fa[v]){ DAG[fa[v]].push_back(fa[u]);in[fa[u]]++; } } } while(!que.empty())que.pop(); for( i = 1 ; i <= scc_cnt; i++) if(!in[i])que.push(i); topsort(); //输出 for(i = 2; i < 2*n; i += 2){ if(i!=2)printf(" "); if(color[fa[i]] == color[fa[0]] )printf("%dw",i/2); else printf("%dh",i/2); } puts(""); } return 0; }