UVa 10305

题意

假设有n个变量,还有m个二元组(u, v),分别表示变量u小于v。那么,所有变量从小大排列起来应该是什么样子的呢?例如,有4个变量a, b, c, d,若已知a < b,c < b,d < c,则这4个变量的排序可能是a < d < c < b。尽管还有其他可能(如d < a < c < b),你只需找出其中一个即可

思路

无环图DAG才存在拓扑排序, 用mrk[]标记三种状态: -1(正在访问), 0(未访问), 1(访问过且已返回)
如果递归dfs遇到-1说明是有环图, 则不存在拓扑排序

AC代码

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

const int maxn = 100 + 50;
int dag[maxn][maxn];
int t[maxn], mrk[maxn];
int n, m, tp;

bool dfs( int x ){
    mrk[x] = -1;
    for( int i = 1; i <= n; i++ ){
        if( dag[x][i] ){
            if( mrk[i] == -1 )   return false;
            else if( !mrk[i] && !dfs(i) )  return false;
        }
    }
    mrk[x] = 1;
    t[--tp] = x;
    return true;
}

bool topo()
{
    tp = n;
    for( int i = 1; i <= n; i++ )
        if( !mrk[i] && !dfs(i) )
            return false;
    return true;
}

int main()
{
    int a, b;
    while( scanf("%d%d",&n, &m) == 2 && n ){
        memset(dag, 0, sizeof(dag));
        memset(mrk, 0, sizeof(mrk));
        while( m-- ){
            scanf("%d%d",&a,&b);
            dag[a][b] = 1;
        }
        topo();
        for( int i = 0; i < n; i++ ){
            if( i != 0 )    putchar(' ');
            printf("%d",t[i]);
        }
        putchar('
');
    }
    return 0;
}
原文地址:https://www.cnblogs.com/JinxiSui/p/9740595.html