【Vj作業】【拓撲排序經典理解題】Ordering Tasks 1、Kahn演算法;2、基於DFS的演算法。

來源:互聯網
上載者:User

標籤:題目   說明   font   each   ++i   做什麼   clu   ted   bool   

2018-02-13

連結   https://cn.vjudge.net/contest/211129#problem/D

John has n tasks to do. Unfortunately, the tasks are not independent and the execution of one task is only possible if other tasks have already been executed.
Input
The input will consist of several instances of the problem. Each instance begins with a line containing two integers, 1 ≤ n ≤ 100 and m. n is the number of tasks (numbered from 1 to n) and m is the number of direct precedence relations between tasks. After this, there will be m lines with two integers i and j, representing the fact that task i must be executed before task j. An instance with n = m = 0 will ?nish the input.
Output
For each instance, print a line with n integers representing the tasks in a possible order of execution.
Sample Input
5 4 1 2 2 3 1 3 1 5 0 0
Sample Output
1 4 2 5 3

感想:

  剛開始學拓撲排序,學了下面兩種方法去做這道經典的簡單題:1、Kahn演算法;2、基於DFS的演算法(用得比較多)。說實話,完全看懂花了一個晚上一個早上,實現基本上也是跟人家的實現沒差的,雖然很不喜歡這麼不獨立地做題,但是事實水平還不到,也是剛學嘛...什麼時候做什麼事,學習有方法,怎麼學有效率,還在摸索...據說兩者複雜度一樣都是O(V+E),之前對複雜度的計算有很多誤解,現在開始遇到一種演算法就自己算一下,慢慢理解進去,也能培養做題前計算複雜度的習慣,同時方便以後做題。學得差不多了會把所有演算法的複雜度自己整理一遍。

Kahn代碼:

     /*拓撲排序*/ #include<cstdio>               #include<cstring>  #include<vector>  #include<queue>                   // using namespace std;  const int N = 105;  int n,m,son[N],topoSort[N],t;    //son是用來儲存入度的 toposort顧名思義就是存放題目要求的序列 char O[2*N];  vector<int>G[N];                 //vector關聯頂點   G[N]接下來是用來斷弧的   void init(){      for(int i=1; i<=n; ++i){          G[i].clear();      }      memset(son, 0, sizeof(son));  }    int main(){      int u,v;      while(scanf("%d%d",&n,&m)&&n+m){          init();          for(int i=0; i<m; ++i){                   //這些地方i的初始值都不是隨意的,要小心,老是出錯            scanf("%d%d",&u,&v);               G[u].push_back(v);              ++son[v];          }          int num=n;          queue<int>q;                                // 先進先出,類似排隊那樣,先進去的元素最先出去的一種資料結構。        for(int i=1; i<=n; ++i){              if(!son[i]) q.push(i);               //將0入度的點推入棧         }          int pos=0;                      while(!q.empty()){                     // empty    判斷容器是否為空白,如果為空白則返回true 這裡就是為非空的時候執行while             int t=q.front();              q.pop();              topoSort[pos++] = t;              for(int v=0; v<G[t].size(); ++v)       //斷弧  注意寫法                 if(--son[G[t][v]]==0)                                   q.push(G[t][v]);               //kahn的複雜度為O(n+m)  其實是n的線性階加上這裡去弧的次數 (也就是看最裡面的迴圈次數,這裡就是m)        }          for(int i=0; i<pos; ++i){              if(!i)printf("%d",topoSort[i]);              else printf(" %d",topoSort[i]);          }          printf("\n");      }      return 0;  }  

基於DFS的演算法(運用遞迴,要判斷是否為DAG) 

#include<string.h>#include<cmath>#include<cstdio>#include<algorithm>#include<iostream>#include<vector> #include<queue>using namespace std;int n,m;int vis[105];                 //標記int topo[105]; int G[105][105];int t;bool dfs(int u){    vis[u]=-1;                //表示正在訪問 1表示已經訪問過 0表示沒有訪問過    for(int v=1;v<=n;v++)    {        if(G[u][v])              {            if(vis[v]==-1) return false;         // 如果存在有向環,失敗退出            if(!vis[v]&&!dfs(v)) return false; //!vis[v]是為了檢驗這個點是否已經被訪問過 訪問過就不dfs 不然會重複存入 實際效果就是省略一個if啦,想了好久唉         }                                        //以後可以這樣寫     }    vis[u]=1; topo[--t]=u;    return true;}bool toposort(){       t=n;    memset(vis,0,sizeof(vis));    for(int u=1;u<=n;u++)    {        if(!vis[u]&&!dfs(u)) return false;//只有vis[u]是0時 進行dfs 而且存在環的時候才返回false   vis[u]=1說明已經訪問過 就不dfs了 避免改變vis的值            }    return true;} int main(){     int a,b;   while(~scanf("%d%d",&n,&m)&&m+n) // 注意輸入那裡的結束條件不能是 n&&m,因為m可能是0   {         memset(G,0,sizeof(G));         for(int i=1;i<=m;i++)       {         scanf("%d%d",&a,&b);         G[a][b]=1;        }           if(toposort())       {             for(int i=0;i<n;i++)             if(!i) printf("%d",topo[i]);          else   printf(" %d",topo[i]);          printf("\n");                }             }    } 

 

【Vj作業】【拓撲排序經典理解題】Ordering Tasks 1、Kahn演算法;2、基於DFS的演算法。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.