Book--Topological Sort

 什么拓扑排序呢?简单的说,有那么些个二元组(u,v),表示u要在v之前(u<v),现在要将所有元素按照二元组的规则排序。

好了,不扯了,看看度娘怎么讲的吧:对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若 ∈E(G),则u在线性序列中出现在v之前。 

先来看看佳哥牛牛怎么想的:

int used[MAXN];//用来记录有没有访问过
int topo[MAXN] , t; 
bool dfs( int u )
{
    used[u] = -1;//表示已访问,且为当前访问点
    for( int v = 0 ; v < n ; v ++ )
    {
        if ( G[u][v] )//G的图应该事先建立成:有二元组关系的为1,其余的为0
        {
            if ( used[v] < 0 ) return false;//存在有向环,返回false
            else if( !used[v] && !dfs( v )) return false;//事先未访问,且从该点深搜失败,返回false
        }
    }
    used[u] = 1;
    topo [ --t ] = u;//这个记录的顺序和二元组大小判断顺序相反(待验证)
    return true;
}
bool toposort(
{
    t = n;
    memset( used , 0 , sizeof(used));
    for( int u = 0 ; u < v ; u ++)
    {
        if ( !dfs(u) ) return false;
    }
    return true;
}

 

 


没错,dfs思想在这里的确很神奇,看来真正难的是算法的思想,而非其代码。

下面,看看百科大大提供的:
实现的基本方法

拓扑排序方法如下:
(1)从有向图中选择一个没有前驱(即入度为0)的顶点并且输出它.
(2)从网中删去该顶点,并且删去从该顶点发出的全部有向边.
(3)重复上述两步,直到剩余的网中不再存在没有前趋的顶点为止.

bool TopologicalSort(int a[][101]) //可以完成拓扑排序则返回True
{
    int n = a[0][0], i, j;
    int into[101], ans[101];
    memset(into, 0, sizeof(into));
    memset(ans, 0, sizeof(ans));
    for (i = 1; i <= n; i++)
    {
        for (j = 1; j <= n; j++)
        {
            if (a[i][j] > 0)
            into[j]++;//into记录到某个点有多少条路(即作为二元组第二元素的次数)
        }
    }
    into[0] = 1;//为了配合下面的j=0;into[j]!=0 
    for (i = 1; i <= n; i++)
    {
        j = 0;
        while (into[j] != 0)
        {
            j++;
            if (j > n)
            return false;
        }
        ans[i] = j;//从前到后找到第一个是0使into【j】== 0 的 j 值
        into[j] = -1;//相当于从图中删除该点
        for (int k = 1; k <= n; k++)
        {
            if (a[j][k] > 0)
            into[k]--;//删从该点出发的所有有向边。
        }
    }
    for (i = 1; i <= n; i++)
    {
        cout << ans[i] << " ";
    }
    cout << endl;
    return true;
}

 

 

 

posted @ 2014-05-27 21:03  Naturain  阅读(117)  评论(0编辑  收藏  举报