浅谈拓扑排序
今天來(lái)講講拓?fù)渑判?/span>
度娘告訴我
對(duì)一個(gè)有向無(wú)環(huán)圖(Directed Acyclic Graph簡(jiǎn)稱DAG)G進(jìn)行拓?fù)渑判?#xff0c;是將G中所有頂點(diǎn)排成一個(gè)線性序列,使得圖中任意一對(duì)頂點(diǎn)u和v,若邊(u,v)∈E(G),則u在線性序列中出現(xiàn)在v之前。通常,這樣的線性序列稱為滿足拓?fù)浯涡?Topological Order)的序列,簡(jiǎn)稱拓?fù)湫蛄小:?jiǎn)單的說(shuō),由某個(gè)集合上的一個(gè)偏序得到該集合上的一個(gè)全序,這個(gè)操作稱之為拓?fù)渑判颉?/span>
維基百科又和我說(shuō)
在圖論中,由一個(gè)有向無(wú)環(huán)圖的頂點(diǎn)組成的序列,當(dāng)且僅當(dāng)滿足下列條件時(shí),稱為該圖的一個(gè)拓?fù)渑判?/strong>(英語(yǔ):Topological sorting)。
也可以定義為:拓?fù)渑判蚴菍?duì)有向無(wú)環(huán)圖的頂點(diǎn)的一種排序,它使得如果存在一條從頂點(diǎn)A到頂點(diǎn)B的路徑,那么在排序中B出現(xiàn)在A的后面[1]。
想了解的自己去找,我就說(shuō)這么多了。
下面步入正題。
看下面的樣例。
不過(guò)要先說(shuō)明一下輸入格式:第一行一個(gè)整數(shù)N,之后的N行,每行若干個(gè)以0為結(jié)尾的整數(shù)。
表示第 i 個(gè)節(jié)點(diǎn)向這些個(gè)節(jié)點(diǎn)都有一條(有向)邊。
那么這張圖的拓?fù)渑判蚓褪? 4 5 3 1當(dāng)然可能并不唯一。
下圖是他拓?fù)渑判蚝笞兊酶又庇^的圖
那么這個(gè)拓?fù)渑判蚴侨绾螌?shí)現(xiàn)的呢。
下面我們就來(lái)看看。
首先定義一個(gè)indgr數(shù)組,表示每個(gè)點(diǎn)的入度(就是有幾條邊是指向他的)。
定義一個(gè)棧。先將所有入度為0的點(diǎn)入棧。然后每次都把棧頂元素輸出,并且彈出記錄下來(lái),還要用一個(gè)cnt記錄輸出次數(shù)。輸出之后,把與相連的點(diǎn)的入度-1,如果-1之后這個(gè)點(diǎn)的入度變?yōu)榱?,那么就將這個(gè)點(diǎn)入棧,重復(fù)此操作,直到所有的點(diǎn)都被輸出一遍,也就是說(shuō)cnt==n的時(shí)候就可以結(jié)束程序了。
下面是代碼:
#include <iostream> #include <cstdio> #include <cstring> #include <stack>using namespace std;stack<int> S; int n, cnt; int son, tot[105]; int indgr[108]; int ed[105][105];int main() {scanf("%d", &n);for(int i=1; i<=n; i++) {while(scanf("%d", &son) == 1) {if(son == 0) {break;}ed[i][++tot[i]] = son;indgr[son]++;}}for(int i=1; i<=n; i++) {if(indgr[i] == 0) {S.push(i);}}while(cnt != n) {int k = S.top();printf("%d ", k);cnt++;S.pop();for(int i=1; i<=tot[k]; i++) {indgr[ed[k][i]]--;if(indgr[ed[k][i]] == 0) {S.push(ed[k][i]);}}}return 0; }?
作者:wlz 出處:http://www.cnblogs.com/bljfy/p/8729163.html本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁(yè)面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利。
轉(zhuǎn)載于:https://www.cnblogs.com/bljfy/p/8729163.html
總結(jié)
- 上一篇: Javascript json转对象(互
- 下一篇: typescript 动态给class添