[知識點]拓撲排序

來源:互聯網
上載者:User

標籤:

// 此博文為遷移而來,寫於2015年2月24日,不代表本人現在的觀點與看法。原始地址:http://blog.sina.com.cn/s/blog_6022c4720102vspe.html

 

1、前言在瞭解拓撲排序之前,我們先來看一道題目以更好的理解:        一個較大的工程往往被劃分成許多子工程,我們把這些子工程稱作活動(activity)。在整個工程中,有些子工程(活動)必須在其它有關子工程完成之後才能開始,也就是說,一個子工程的開始是以它的所有前序子工程的結束為先決條件的,但有些子工程沒有先決條件,可以安排在任何時間開始。為了形象地反映出整個工程中各個子工程(活動)之間的先後關係,可用一個有向圖來表示,圖中的頂點代表活動(子工程),圖中的有向邊代表活動的先後關係,即有向邊的起點的活動是終點活動的前序活動,只有當起點活動完成之後,其終點活動才能進行。通常,我們把這種頂點表示活動、邊表示活動間先後關係的有向圖稱做頂點活動網(Activity On Vertex network),簡稱AOV網。          課程代號      課程名稱        先修課程           C1          高等數學             無           C2          程式設計基礎      無           C3          離散數學             C1,C2           C4          資料結構             C3,C5           C5          演算法語言             C2           C6          編譯技術             C4,C5           C7          作業系統             C4,C9           C8          普通物理             C1           C9          電腦原理         C8 其AOV網: 

2、什麼是拓撲排序?       一個AOV網應該是一個有向非循環圖,即不應該帶有迴路,因為若帶有迴路,則迴路上的所有活動都無法進行。一個具有三個頂點的迴路,由邊可得B活動必須在A活動之後,由邊可得C活動必須在B活動之後,所以推出C活動必然在A活動之後,但由邊可得C活動必須在A活動之前,從而出現矛盾,使每一項活動都無法進行。這種情況若在程式中出現,則稱為死結或死迴圈,是應該必須避免的。       在AOV網中,若不存在迴路,則所有活動可排列成一個線性序列,使得每個活動的所有前驅活動都排在該活動的前面,我們把此序列叫做拓撲序列(Topological order),由AOV網構造拓撲序列的過程叫做拓撲排序(Topological sort)。AOV網的拓撲序列不是唯一的,滿足上述定義的任一線性序列都稱作它的拓撲序列。例如,下面的三個序列都是的拓撲序列,當然還可以寫出許多。    (1) C1,C8,C9,C2,C3,C5,C4,C7,C6    (2) C2,C1,C3,C5,C4,C6,C8,C9,C7    (3) C1,C2,C3,C8,C9,C5,C4,C6,C7 3、有什麼作用?       除了上面我們之前我們展示的一道題目,拓撲排序的應用是比較廣泛的。下面我們再看一個例子: 士兵排隊 Soldier.cpp<1>問題描述       有N名士兵(1<=N<=26),編號依次為A,B,C,……進行隊列訓練時,指揮官要把一些士兵從高到矮依次排成一行,但現在指揮官不能直接獲得每個士兵的身高資訊,只能獲得“P1比P2高”這樣的比較結果(P1,P2∈{A,B,…Z},記為P1>P2),如“A>B”表示A比B高。編一程式,根據所得到的比較結果求出合格排隊方案。註:比較結果中沒有涉及到計程車兵不參加排隊。       例如,設有3個士兵,A、B、C,給出關係(A,B),(B,C)。其中(A,B)表示士兵A高於B,當上面的關係給出之後,可以將他們排成一隊:ABC。 <2>輸入       通過檔案輸入,每個比較結果在檔案中佔一行。<3>輸出       若輸入資料無解或不能唯一確定,則輸出“NO  ANSWER!”,否則從高到矮依次輸出每一個士兵的編號,中間無分隔字元,並把結果寫入文字檔中。 <4>輸入範例A>BB>FF>D<5>輸出範例ABFD 代碼如下: #include<cstdio>#include<cstdlib>#define MAXN 28 struct edge{  int next,v;};edge list[MAXN*2];int head[MAXN],tot,n,have[MAXN],ListNum[MAXN],del[MAXN],get,ans[MAXN]; void AddList(char strU,char strV){  int u=strU-64,v=strV-64;  have[u]=have[v]=1;  tot++;  list[tot].v=v;  list[tot].next=head[u];  head[u]=tot;  ListNum[v]++;} void init(){  char s[4];  freopen("3.in","r",stdin);  freopen("3.out","w",stdout);  while (scanf("%s",s)!=EOF) AddList(s[0],s[2]);  for (int i=1;i<=26;i++)    if (have[i]==1) n++;} int check(){  for (int i=1;i<=26;i++)    if (del[i]!=1 && have[i]==1) return 0;  return 1;} void DFS(int now,int dep){  del[now]=1;  for (int x=head[now];x!=0;x=list[x].next)    ListNum[list[x].v]--;  ans[dep]=now;  if (check()==1)   {    if (get==1) { printf("NO ANSWER!"); exit(0); }    else { get=1; return; }  }  for (int i=1;i<=26;i++)    if (ListNum[i]==0 && del[i]!=1 && have[i]==1) DFS(i,dep+1);  for (int x=head[now];x!=0;x=list[x].next)    ListNum[list[x].v]++;  del[now]=0;}  int main(){  init();  for (int i=1;i<=26;i++)     if (ListNum[i]==0 && have[i]==1) DFS(i,1);  if (get==0) printf("NO ANSWER!");  else for (int i=1;i<=n;i++) printf("%c",ans[i]+64);  return 0;}

 

[知識點]拓撲排序

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.