拓撲排序,判斷有向圖中是否有環


【原創】

今天我們來聊聊有向圖中環的判斷,在數據結構中我們知道,通過拓撲排序可以判斷有向圖中是否存在環,對於有向圖的存儲我們采用鄰接表的形勢,這里為了簡化鏈表的操作,我們省略了鏈表,避免了指針的麻煩,直接采用了c++中的vector來模擬鏈表,操作更加的方便;具體詳細的使用,建議百度一下,這里不多說,至於拓撲排序的具體思想,相信大家應該都了解,那么直接上代碼,如果有不理解的,建議查閱數據結構書籍,搞懂思想,結合這份代碼,很好理解

 1 #include <stdio.h>
 2 #include <queue>
 3 #include<vector>
 4 #include<stdlib.h>
 5 using namespace std;
 6 //拓撲排序中使用的對列和模擬鏈表的向量
 7 vector<int> edge[501];//鄰接鏈表
 8 queue<int> Q;//保存入股為0的節點
 9 int main(){
10  //拓撲排序,判斷一個有向圖中是否存在環
11     int inDegree[501];//統計每一個節點的入度;
12     int n,m;
13     while (scanf("%d%d",&n,&m)!=EOF) {//多組數據的測試
14         if (m==0&&n==0) break;
15         for (int i = 0; i<n; i++) {
16             inDegree[i] = 0;//剛開始的節點入度均為0
17             edge[i].clear();//清除前一組數據的殘留
18         }
19         while(m--!=0){
20             int a,b;//輸入m組節點關系
21             scanf("%d%d",&a,&b);
22             inDegree[b]++;//出現了一條邊指向b,所以入度增加1
23             edge[a].push_back(b);//
24         }
25         while (Q.empty()==false) {
26             Q.pop();//清除之前的數據
27         }
28         for(int i = 0;i<n;i++){
29             if (inDegree[i]==0) {
30                 Q.push(i);
31             }
32         }
33             int cnt = 0;
34             while (Q.empty()==false) {//當隊列中還有入度為0的點
35                 int newP = Q.front();
36                 Q.pop();//這里不需要保留拓撲排序的路徑,因而不需要保存彈出來的值
37                 cnt++;
38                 for (int i = 0; i<edge[newP].size(); i++) {
39                     inDegree[edge[newP][i]]--;//去除一條邊后,將所指向的后繼節點的如度減1
40                     if (inDegree[edge[newP][i]]==0) {
41                         Q.push(edge[newP][i]);
42                     }
43                 }
44             }
45         if (cnt==n) {
46             puts("YES");
47         }else{
48             puts("NO");
49         }
50     }
51 return 0;
52 }
53 /**************************************************************
54     Problem: 1448
55     User: Numen_fan
56     Language: C++
57     Result: Accepted
58     Time:10 ms
59     Memory:1064 kb
60 ****************************************************************/

注意:這份代碼,輸入兩個數字n、m,n表示有n個節點,m表示有m對關系,即接下來有m行,每一行兩個數字a、b,表示a到b有邊,;同時這里可以測試多組數據,這種編程思想是很好的,不用測試一組數據酒run一次,麻煩,同時,看到代碼35-37行中,這里只計算cnt總數,並沒有保存拓撲排序的序列,如果需要求出序列,也很容易吧,將newP節點保存即可,本例子中采用queue隊列來保存入度為0 的節點,那么其實也可以用stack來保存,原因很簡單,因為拓撲排序不唯一;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM