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