poj 3648 Wedding(2-sat--拓扑排序输出可行解)


题目链接:

点击打开链接

题目大意:

给出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 ;
}



智能推荐

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
China Scenic Area
© 2014-2019 ITdaan.com 粤ICP备14056181号  

赞助商广告