<數據結構>XDOJ323.判斷有向圖中是否有環


問題與解答

問題描述
判斷有向圖中是否有環。
輸入格式
輸入數據第一行是一個正整數,表示n個有向圖,其余數據分成n組,每組第一個為一個整數,表示圖中的頂點個數n,頂點數不超過100,之后為有向圖的鄰接矩陣。
輸出格式
輸出結果為一行,如果有環,則輸出1,如果無環,則輸出0。按順序輸出這n個有向圖的判斷結果,前后結果的輸出不加空格。
樣例輸入
3
2
0 1
0 0
4
0 1 0 0
0 0 0 1
0 0 0 1
1 0 0 0
3
0 1 1
0 0 0
0 0 0
樣例輸出
010

//判斷有向圖中是否有環
//本質:拓撲排序
#include<stdio.h>
#include<queue>
#include<algorithm>
using namespace std;
#define MaxN 100  //最大頂點數
int n;  //頂點數
int G[MaxN][MaxN];  //鄰接矩陣保存圖
int InDegree[MaxN] = {0};  //保存頂點入度
void TopoSort();     //拓撲排序判斷有向環

int main(){
    int num, i, j, flag;
    scanf("%d", &num);
    while(num--){   //多點輸入:執行num次
        scanf("%d", &n);
        fill(InDegree,InDegree+MaxN,0);  //每次都要重置InDegree數組!
        for(i = 0; i < n; i++){   //輸入圖的鄰接矩陣
            for(j = 0; j < n; j++){
                scanf("%d", &flag);
                G[i][j] = flag;
                if(flag != 0)
                   InDegree[j]++;
            }
        }
        TopoSort();  //拓撲排序
    }
}

void TopoSort(){
    queue<int> q;
    int u,v;
    int node = 0;
    for(u = 0; u < n; u++){  //將入度為0的頂點入隊
        if(InDegree[u] == 0){
            q.push(u);
        }
    }
    while(!q.empty()){  //若隊列非空
        u = q.front();
        q.pop();  //u出隊
        for(v = 0; v < n; v ++){  //掃描u的鄰接點
            if(G[u][v] != 0){
                InDegree[v]--;  //鄰接點入度-1
                if(InDegree[v] == 0)  //若入度變為0,入隊
                    q.push(v);
            }
        }
        node++;  //已完成拓撲排序的頂點數目+1
    }
    if(node == n) printf("0");  //拓撲排序成功:無有向環
    else         printf("1");   //拓撲排序失敗:存在有向環
}

題后反思

  1. 判斷有向圖中是否有環: 拓撲排序
    • 拓撲排序易錯點:兩層判斷是嵌套關系,否則會進入死循環!!!
    if(G[u][v] != 0){
                InDegree[v]--;  //鄰接點入度-1
                if(InDegree[v] == 0)  //若入度變為0,入隊
                    q.push(v);
            }
    
  2. 寫多點測試題時注意全局變量的初始化【fill(InDegree,InDegree+MaxN,0); //每次都要重置InDegree數組!】否則樣例輸出011


免責聲明!

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



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