拓撲排序
一.定義
對一個有向無環圖(Directed Acyclic Graph簡稱DAG)G進行拓撲排序,是將G中所有頂點排成一個線性序列,使得圖中任意一對頂點u和v,若<u,v> ∈E(G),則u在線性序列中出現在v之前。
通常,這樣的線性序列稱爲滿足拓撲次序(Topological Order)的序列,簡稱拓撲序列。
注意:
1)只有有向無環圖才存在拓撲序列;
2)對於一個DAG,可能存在多個拓撲序列;
如:
該DAG的拓撲序列爲A B C D或者A C B D
而此有向圖是不存在拓撲序列的,因爲圖中存在環路
二.拓撲序列算法思想
(1)從有向圖中選取一個沒有前驅(即入度爲0)的頂點,並輸出之;
(2)從有向圖中刪去此頂點以及所有以它爲尾的弧;
重複上述兩步,直至圖空,或者圖不空但找不到無前驅的頂點爲止。
三.代碼實現
採用鄰接矩陣實現,map[i][j]=0,表示節點i和j沒有關聯;map[i][j]=1,表示存在邊<i,j>,並且j的入度加1;
#include<iostream>
#include<stdlib.h>
#include<stdio.h>
#define MAX 100
usingnamespace std;
void toposort(int map[MAX][MAX],int indegree[MAX],int n)
{
int i,j,k;
for(i=0;i<n;i++) //遍歷n次
{
for(j=0;j<n;j++) //找出入度爲0的節點
{
if(indegree[j]==0)
{
indegree[j]--;
cout<<j<<endl;
for(k=0;k<n;k++) //刪除與該節點關聯的邊
{
if(map[j][k]==1)
{
indegree[k]--;
}
}
break;
}
}
}
}
int main(void)
{
int n,m; //n:關聯的邊數,m:節點數
while(scanf("%d %d",&n,&m)==2&&n!=0)
{
int i;
int x,y;
int map[MAX][MAX]; //鄰接矩陣
int indegree[MAX]; //入度
memset(map,0,sizeof(map));
memset(indegree,0,sizeof(indegree));
for(i=0;i<n;i++)
{
scanf("%d %d",&x,&y);
if(!map[x][y])
{
map[x][y]=1;
indegree[y]++;
}
}
toposort(map,indegree,m);
}
return0;
}