拓撲排序 topsort詳解


1.定義

    對一個有向無環圖G進行拓撲排序,是將G中所有頂點排成一個線性序列,通常,這樣的線性序列稱為滿足拓撲次序(Topological Order)的序列,簡稱拓撲序列。

 舉例:

我們起床穿褲子和鞋子時,相信大部分人的順序是這樣的,先穿上內褲,然后再穿上褲子,再穿上襪子,然后才是鞋子。那么我們把這些步驟分解:

(1)穿內褲

(2)穿褲子

(3)穿襪子

(4)穿鞋子

我們把這四個步驟,按照上述的順序給排一下就是所謂的拓撲排序 。

2.注意

   1)只有有向無環圖才存在拓撲序列;

   2)對於一個DAG,可能存在多個拓撲序列;

   如:

   

該DAG的拓撲序列為A B C D或者A C B D

 

而此有向圖是不存在拓撲序列的,因為圖中存在環路

3..拓撲序列算法思想

 (1)從有向圖中選取一個沒有前驅(即入度為0)的頂點,並輸出之;

 (2)從有向圖中刪去此頂點以及所有以它為尾的弧;

     重復上述兩步,直至圖空,或者圖不空但找不到無前驅的頂點為止。
4.代碼
#include<cstdio>
#include<cstring>
int ans[510][510];//記錄兩人是否進行了比賽
int n,indegree[510];//記錄前驅個數
int queue[510];//保存拓撲
void topsort()
{
    int i,j,top,k=0;
    for(j=0; j<n; ++j)
    {
        for(i=1; i<=n; ++i)
        {
            if(indegree[i]==0)//前驅為零即是當前第一名
            {
                top=i;
                break;
            }
        }
        queue[k++]=top;//當前第一名入隊列,也可以直接輸出
        indegree[top]=-1;//前驅數量更新為-1,避免重復入隊列
        for(i=1; i<=n; ++i)
        {
            if(ans[top][i])//將前驅中含有當前第一名的前去數量減一
                indegree[i]--;
        }
    }
    for(i=0; i<k-1; ++i)
        printf("%d ",queue[i]);
    printf("%d\n",queue[n-1]);
}

int main()
{
    int i,a,b,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        memset(indegree,0,sizeof(indegree));//數組初始化為0
        memset(ans,0,sizeof(ans));//數組初始化為0
        for(i=0; i<m; ++i)
        {
            scanf("%d%d",&a,&b);
            if(ans[a][b]==0)
            {
                ans[a][b]=1;//記錄是否進行了比賽
                indegree[b]++;//記錄前驅數量
            }
        }
        topsort();
    }
    return 0;
}

 

    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM