题目链接:
点击打开链接
题目大意:
给出n对父亲,第0对是新郎新娘,其中有的两个人有**关系,不能坐在一起,夫妻不能坐在一起,问最终应当如何做,随便给出一种方案即可。
题目分析:
2-sat模板题,建边是选谁之后必选谁,也就是i和j不能同坐,那么i->j' , j->i'两条边需要建立,求解啥的直接上模板,简单粗暴
代码如下:
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <vector> #include <stack> #include <queue> #define MAX 1004 using namespace std; vector<int> e[MAX]; vector<int> g[MAX]; stack<int> s; bool vis[MAX]; bool inStack[MAX]; int low[MAX],dfn[MAX]; int belong[MAX]; int n,m,step,t; int conflict[MAX]; int col[MAX]; int in[MAX]; void init ( ) { for ( int i = 0 ; i <= 2*n ; i++ ) { e[i].clear(); vis[i] = 0; inStack[i] = 0; in[i] = 0; g[i].clear(); col[i] = 0; } while ( !s.empty()) s.pop(); } void add ( int a , int b ) { e[a].push_back ( b ); } void tarjan ( int u ) { vis[u] = true; step++; s.push ( u ); inStack[u] = true; low[u] = dfn[u] = step; for ( int i = 0 ; i < e[u].size() ; i++ ) { int v = e[u][i]; if ( !vis[v] ) { tarjan ( v ); low[u] = min ( low[u] , low[v] ); } else if ( inStack[v] ) low[u] = min ( low[u] , dfn[v] ); } if ( low[u] == dfn[u] ) { t++; while ( true ) { int v = s.top(); s.pop(); belong[v] = t; inStack[v] = false; if ( v == u ) break; } } } //反向建图 void rebuild ( ) { for ( int i = 0 ; i < 2*n ; i++ ) for ( int j = 0 ; j < e[i].size() ; j++ ) { int a = belong[i],b=belong[e[i][j]]; if ( a != b ) { in[a]++; g[b].push_back ( a ); } } } void topsort ( ) { int i,j; queue<int> q; for ( int i = 1 ; i < t ; i++ ) { if (!in[i]) q.push ( i ); } while (!q.empty()) { int u = q.front(); q.pop(); if ( !col[u] ) { col[u] = 1; col[conflict[u]] = 2; } for ( int i = 0 ; i < g[u].size(); i++ ) { int v = g[u][i]; in[v]--; if ( !in[v] ) q.push ( v ); } } } void solve ( ) { t = 0,step = 0; for ( int i = 0 ; i < 2*n ; i++ ) if (!vis[i]) tarjan ( i ); for ( int i = 0 ; i < 2*n ; i += 2 ) { if ( belong[i] == belong[i+1]) { puts("bad luck"); return; } int a = belong[i] , b = belong[i+1]; conflict[a] = b; conflict[b] = a; } rebuild (); topsort (); for ( int i = 2 ; i < 2*n ; i += 2 ) { if ( i != 2 ) printf ( " "); if ( col[belong[i]] == col[belong[0]]) printf ( "%dw" , i/2 ); else printf ( "%dh" , i/2 ); } puts ( ""); } int main ( ) { while ( ~scanf ( "%d%d" , &n , &m ) , n+m ) { init (); char c1,c2; int d1,d2; int i,j,ii,jj; while ( m-- ) { scanf ( "%d%c %d%c" , &d1 , &c1 , &d2 , &c2 ); if ( c1 == 'h' ) { i = 2*d1+1; ii = i-1; } else { i = 2*d1; ii = i+1; } if ( c2 == 'h' ) { j = 2*d2+1; jj = j-1; } else { j = 2*d2; jj = j+1; } add ( i , jj ); add ( j , ii ); } add ( 0 , 1 ); solve ( ); } return 0 ; }