拓扑排序(Topological Sorting)

2017-08-04  本文已影响0人  Gitfan

拓扑排序(Topological Sorting)
拓扑排序(Topological Sorting)是一个有向无环图(DAG, Directed Acyclic Graph)的所有顶点的线性序列。DAG的判定
拓扑排序的时间复杂度为O ( V + E ),因为DFS的时间复杂度度为O ( V + E )
该序列必须满足下面两个条件:

它是一个 DAG 图,那么如何写出它的拓扑排序呢?这里说一种比较常用的方法:

重复 1 和 2 直到当前的 DAG 图为空或当前图中不存在无前驱的顶点为止。后一种情况说明有向图中必然存在环。



于是,得到拓扑排序后的结果是 { 1, 2, 4, 3, 5 }。

通常,一个有向无环图可以有一个或多个拓扑排序序列。

#include <cstdio>
#include<cstring>
#include<vector>
using namespace std;
const int MAXN=100010;
vector<int> graph[MAXN];
int in[MAXN];
void topoSort(int n)
{
    vector<int> zero;//0入度点
    vector<int> result;//排序结果
    for(int i=1;i<=n;i++)
    {
        if(in[i]==0) zero.push_back(i);
    }
    while(!zero.empty())
    {
        int curr=zero.back();
        zero.pop_back();
        result.push_back(curr);
        int len=graph[curr].size();
        for(int i=0;i<len;i++)
        {
            int v=graph[curr][i];
            in[v]--;
            if(in[v]==0) zero.push_back(v);
        }
    }
    if(result.size()!=n)
    {
        printf("Not DAG, fail\n");
        return;
    }
    for(int i=0;i<result.size();i++)
    {
        printf("%d\n",result[i]);
    }
}
int main()
{
    int n,m,a,b;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        memset(graph,0,sizeof(graph));
        memset(in,0,sizeof(in));
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&a,&b);
            graph[a].push_back(b);
            in[b]++;
        }
        topoSort(n);
    }
}

还有一种直观的方法是利用DFS,容易知道拓扑排序的序列为所有顶点的逆后续排列(ReversePostOrder)

#include <cstdio>
#include<cstring>
#include<vector>
#include<stack>
using namespace std;
const int MAXN=100010;
vector<int> graph[MAXN];
stack<int> result;//排序结果
int vis[MAXN];
bool DFS(int u)
{
    if(vis[u]==2) return true;
    vis[u]=2;
    int len=graph[u].size();
    for(int i=0;i<len;i++)
    {
        int v=graph[u][i];
        if(vis[v]==0)
        {
            if(DFS(u)) return true;
        }
        else if(vis[v]==2) return true;
    }
    vis[u]=1;
    result.push(u);
    return false;
}
void topoSort(int n)
{
    memset(vis,0,sizeof(vis));
    bool flag=false;
    for(int i=1;i<=n;i++)
    {
        if(vis[i]==0)
        {
            if(DFS(i))
            {
                flag=true;
                break;
            }
        }
    }
    if(flag)
    {
        printf("Not DAG, fail\n");
        return;
    }
    while(!result.empty())
    {
        printf("%d\n",result.top());
        result.pop();
    }
}
int main()
{
    int n,m,a,b;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        memset(graph,0,sizeof(graph));
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&a,&b);
            graph[a].push_back(b);
        }
        topoSort(n);
    }
}
上一篇下一篇

猜你喜欢

热点阅读