poj 3648 Wedding

来源:互联网 发布:知及之仁不能守之 编辑:程序博客网 时间:2024/05/20 10:23

题意:

新郎新娘宴会,宴会上一共有 n 对夫妇,编号分别为 0 ~ n - 1,其中新郎新娘编号为 0,丈夫为 h,妻子为 w 。

宴会的长桌上,新郎新娘各坐一边,两边人数各为 n。在所有人中,存在 m 对异常关系,现在要求,新娘对面的那一边所有人之间不能存在异常关系,要求你求出新娘的这边的坐的人。这里的异常关系指偷情(男男、男女、女女)。

分析:

矛盾关系,有异常关系的两人不能同时存在,即 a && b == 0。(a 与 b 两个可以选择其中一人做新郎这一边,也可以选择都坐在新娘这一边)

需要注意的是,新郎必须在,因此必须在图中加一条 0 -> n 的边。(证明请找度娘,谢谢)

此外,有一点很要命,输入不要"%s%s",测试数据中存在无空格输入的现象,用“%d%c %d%c”吧,这个,我表示我画了一个小时陷在这个坑里,悲催呀。。。

#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#include<queue>using namespace std;const int maxn = 11000;const int inf = 1000000000;vector<int>edge[maxn];int n, m;int tmpdfn, dfn[maxn], low[maxn], inst[maxn], belong[maxn], st[maxn], top, scnt;int opp[maxn], in[maxn], color[maxn];vector<int>arc[maxn];queue<int>q;void tarjan( int u ){int i, v, t, size;low[u] = dfn[u] = tmpdfn++;st[top++] = u;inst[u] = 1;size = edge[u].size();for( i = 0; i < size; i++ ){v = edge[u][i];if( dfn[v] == -1 ){tarjan( v );low[u] = min( low[u], low[v] );}else if( inst[v] )low[u] = min( low[u], dfn[v] );}if( dfn[u] == low[u] ){do{ belong[t = st[--top]] = scnt; inst[t] = 0; }while( t != u );scnt++;}}bool SCC(){int i;top = 0;tmpdfn = scnt = 1;memset( dfn, -1, sizeof(dfn) );memset( inst, 0, sizeof(inst) );for( i = 1; i <= n * 2; i++ )if( dfn[i] == -1 )tarjan( i );for( i = 1; i <= n; i++ )if( belong[i] == belong[i + n] )return false;return true;}void rebuild(){memset( in, 0, sizeof(in) );int u, v, i, size;for( i = 1; i <= n * 2; i++ )arc[i].clear();for( u = 1; u <= n * 2; u++ ){size = edge[u].size();for( i = 0; i < size; i++ ){v = edge[u][i];if( belong[u] != belong[v] ){arc[belong[v]].push_back( belong[u] );in[belong[u]]++;}}}}void topusort(){int i, j, u, v, size;while( !q.empty() )q.pop();memset( color, 0, sizeof(color) );for( i = 1; i < scnt; i++ )if( !in[i] )q.push( i );while( !q.empty() ){u = q.front();q.pop();if( !color[u] )color[u] = 1, color[opp[u]] = 2;size = arc[u].size();for( i = 0; i < size; i++ ){v = arc[u][i];in[v]--;if( !in[v] )q.push( v );}}}int main(){int i, j, a, b, aa, bb;char s1, s2;while( ~scanf( "%d%d", &n, &m ), n + m ){for( i = 1; i <= n * 2; i++ )edge[i].clear();while( m-- ){scanf( "%d%c %d%c", &a, &s1, &b, &s2 );// %s%s 输入有误,案例中输入无空格a++;b++;aa = s1 == 'w' ? 0 : 1;bb = s2 == 'w' ? 0 : 1;edge[a + aa * n].push_back( b + (!bb) * n );edge[b + bb * n].push_back( a + (!aa) * n );}edge[1].push_back( 1 + n );if( SCC() ){for( i = 1; i <= n; i++ ){opp[belong[i]] = belong[i + n];opp[belong[i + n]] = belong[i];}rebuild();topusort();for( i = 2; i <= n; i++ )if( color[belong[i]] == color[belong[1]] )printf( "%dw ", i - 1 );else printf( "%dh ", i - 1 );puts("");}elseputs( "bad luck" );}return 0;}//1h 2w 3w 4h 5w 6w 7h 8w 9h