拓撲排序+有向無環圖(DAG)的檢測
拓撲排序的兩張方法:
1.dfs搜尋2.模擬人工的拓撲
兩種方法的效率都是O(V + E)
$$拓撲排序的方法也是有向無環圖檢測的方法
/* 拓撲排序 dfs搜尋 - 鄰接表 可以判斷一個圖是否有環 */ #include <cstdio> #include <vector> #include <stack> using std::vector; using std::stack; const int MAXN = 10; const int INIT = 0; const int GRAY = 1; //參考演算法導論的染色, GRAY表示一條後向邊 const int BLACK = 2; int visit[MAXN]; int time = 0; vector<vector<int>>g(MAXN); stack<int> ans; bool dfs(int p) // recursion遞迴 { visit[p] = GRAY; //表示正被訪問(正在訪問它或者它的子孫)的結點 for (int i = 0; i < g[p].size(); ++i) { int temp = g[p][i]; if (visit[temp] == INIT) { if (dfs(temp) == false) return false; } else if (visit[temp] == GRAY) { //GRAY表示一條後向邊,代表子孫指向祖先,這條邊說明有環 return false; // 有環, 不是DAG(有向無環圖) } } visit[p] = BLACK; //已經被訪問過(或者已經排序好了) ans.push(p); } bool toposort(int N) // 拓撲排序 topological sort O(E + V) { for (int i = 1; i <= N; ++i) // 初始化 { visit[i] = INIT; } time = 0; for (int i = 1; i <= N; ++i) // 圖可能不是連通的 { if (visit[i] == INIT) { if (dfs(i) == false) // 遞迴呼叫dfs return false; } } return true; } void print() { while (!ans.empty()) { printf("%d\n", ans.top()); ans.pop(); } } int main() { freopen("F://input.txt", "r", stdin); int N, v, t; scanf("%d", &N); while (scanf("%d%d", &v, &t) != EOF) { g[v].push_back(t);//構造鄰接表 } if (toposort(N)) print(); else printf("The graph is not a DAG\n"); }
/* 拓撲排序-模擬人工的方法-鄰接表 和dfs的拓撲排序一樣,這個方法也可以判斷一個圖是否有環 第一種沒有優化, 第二種使用了佇列優化 */ #include <cstdio> #include <vector> #include <queue> using std::vector; using std::queue; const int MAXN = 10; vector<vector<int>>g(MAXN); queue<int> ans; // 出隊順序儲存在ans佇列裡面, 也可以保持在陣列中 int indegree[MAXN]; bool toposort_1(int N)//沒有優化,尋找度為0的點每次掃描一遍陣列 O(V*V) { bool flag = true; while (flag) { flag = false; for (int i = 1; i <= N; ++i) { if (indegree[i] == 0) { indegree[i] = -1;// 結點i已經被排序 ans.push(i); flag = true; for (int j = 0; j < g[i].size(); ++j) { int temp = g[i][j]; --indegree[temp]; } } } } if (ans.size() < N) return false; return true; } bool toposort(int N)//佇列優化, 從佇列中找出度為0的結點 O(V + E) { queue<int> que; for (int i = 1; i <= N; ++i) { if (indegree[i] == 0) que.push(i); } while (!que.empty()) { int p = que.front(); ans.push(p); que.pop(); for (int i = 0; i < g[p].size(); ++i) { int temp = g[p][i]; if (--indegree[temp] == 0)//度為0的結點肯定產生在減小入度的地方 que.push(temp); } } if (ans.size() < N)//如果已經排序的少於總結點數,說明圖有環 return false; return true; } void print() { while (!ans.empty()) { printf("%d\n", ans.front()); ans.pop(); } } int main() { freopen("F://input.txt", "r", stdin); int N, v, t; scanf("%d", &N); while (scanf("%d%d", &v, &t) != EOF) { g[v].push_back(t);//構造鄰接表 ++indegree[t]; // t的入度+1 } if (toposort(N)) print(); else printf("The graph is not a DAG\n"); } /* 測試資料: <<資料結構與演算法分析>> p218 9-4圖 7 1 2 1 3 1 4 2 4 2 5 5 4 5 7 7 6 4 3 4 7 4 6 3 6 */
相關推薦
拓撲排序+有向無環圖(DAG)的檢測
參考: 演算法導論第三版 p356, 資料結構與演算法分析p218, 演算法入門經典p110 拓撲排序的兩張方法: 1.dfs搜尋 2.模擬人工的拓撲 兩種方法的效率都是O(V + E)$$拓撲排序的方法也是有向無環圖檢測的方法 /* 拓撲排序 dfs搜尋 - 鄰接表 可
有向無環圖DAG 拓撲排序 程式碼解釋
目錄: DAG定義 舉例描述 實際運用 演算法描述 演算法實戰 演算法視覺化 定義 在圖論中,由一個有向無環圖的頂點組成的序列,當且僅當滿足下列條件時,稱為該圖的一個拓撲排序(英語:Topological sorting)。 每個頂點出現且只出現一
演算法: 有向無環圖(DAG)的拓撲排序
更新: 拓撲排序有2中方法(最後結果可能不同,因為拓撲排序有多解)。 一個簡單的求拓撲排序的演算法是先找出任意一個沒有入邊的頂點,然後將它和它的邊從圖中刪除。然後對剩餘部分使用同樣的操作。 public ArrayList<Integer&g
C#實現有向無環圖(DAG)拓撲排序
對一個有向無環圖(Directed Acyclic Graph簡稱DAG)G進行拓撲排序,是將G中所有頂點排成一個線性序列,使得圖中任意一對頂點u和v,若邊(u,v)∈E(G),則u線上性序列中出現在v之前。通常,這樣的線性序列稱為滿足拓撲次序(Topological Order)的序列,簡稱拓撲序列。簡單的
有向無環圖(DAG)的所有拓撲序列
如果index>length(S(i)),即index的值如果大於集合S(i)的大小了,說明當前集合S(i)中的值都用過了,必須回溯到前一個序列元素result[i-1],將它的值變成它對應集合(S(i-1))中的下一個可能的值.假設之前result[i-1]使用的是S(i-1)[n],那麼現在resu
Spark有向無環圖DAG圖解與演示
目錄:1、有向無環圖 2、程式碼結構 3、程式碼學習步鄹及方法 4、重點程式碼講解 5、程式碼展現 6、執行結果 ——————————————————————————————————— 1、有向無環圖 在圖論中,如果一個有向圖無法從某個頂點出發經過若干條邊回到該點,則這個
Spark的有向無環圖DAG(程式碼及圖解)
目錄: 1、有向無環圖 2、程式碼結構 3、程式碼學習步鄹及方法 4、重點程式碼講解 5、程式碼展現 6、執行結果 ——————————————————————————————————— 1、有向無環圖 在圖論中
圖->有向無環圖->拓撲排序
文字描述 關於有向無環圖的基礎定義: 一個無環的有向圖稱為有向無環圖,簡稱DAG圖(directed acycline graph)。DAG圖是一類較有向樹更一般的特殊有向圖。 舉個例子說明有向無環圖的應用。假如有一個表示式: ((a+b)*(b*(c+d))+(c+d)*e
拓撲排序(判斷是否是有向無環圖)
要進行拓撲排序之前,該圖要是有向無環圖。 排序方法: 1、從有向圖中選取一個沒有前驅的頂點,並輸出之 ;2、從有向圖中刪去此頂點以及所有以它為尾的弧; 3、重複上述兩步,直至圖空,或者圖不空但找不到無前驅的頂點為止。 #include<stdio.h>
【圖論】有向無環圖的拓撲排序
1. 引言 有向無環圖(Directed Acyclic Graph, DAG)是有向圖的一種,字面意思的理解就是圖中沒有環。常常被用來表示事件之間的驅動依賴關係,管理任務之間的排程。拓撲排序是對DAG的頂點進行排序,使得對每一條有向邊(u, v),均有u(在排序記錄中)比v先出現。亦可理解為對某點v而言,只
Java實現拓撲排序:基於鄰接矩陣,針對有向無環圖
public void topoSort(){//僅僅針對有向圖,基本思路是找到一個無後繼的結點,將其刪除,並放到排序陣列的尾端,依次迴圈。直到沒有結點。 int originalVertex
有向無環圖的拓撲排序
拓撲排序只能用於無環圖。// 頂點class Vertex3 { char label; boolean visited; public Vertex3(char label) { this.label = label; visi
最短路模板(二)——用拓撲排序解決有向無環圖中的最短路
測試資料: 8 13 5 4 0.35 4 7 0.37 5 7 0.28 5 1 0.32 4 0 0.38 0 2 0.26 3 7 0.39 1 3 0.29 7 2 0.34 6 2 0.40 3 6 0.52 6 0 0.58 6 4 0.93 測試結果: 5
有向無環圖的拓撲排序(DFS實現)
1.有向無環圖的拓撲排序 // enDegree表示每個頂點的入度,這個資料結構可以從圖的結構求出來 // graph是一個二維陣列,但是這個陣列不是圖的鄰接矩陣,graph[i][j]表示依賴於i的第
算法87-----DAG有向無環圖的拓撲排序
gree 方案 跳過 分享圖片 分享 return tail take != 一、題目:課程排表---210 課程表上有一些課,是必須有修學分的先後順序的,必須要求在上完某些課的情況下才能上下一門。問是否有方案修完所有的課程?如果有的話請返回其中一個符合要求的路徑,否則返
建立有向圖的鄰接表,深度優先遍歷和廣度優先遍歷的遞迴與非遞迴演算法,判斷是否是有向無環圖,並輸出一種拓撲序列
/*(1)輸入一組頂點,建立有向圖的鄰接表,進行DFS(深度優先遍歷)和BFS(廣度優先遍歷)。 寫出深度優先遍歷的遞迴和非遞迴演算法。 (2)根據建立的有向圖,判斷該圖是否是有向無環圖,若是,則輸出其一種拓撲有序序列。*/ #include<stdio.h>
HDU 3249 Test for job (有向無環圖上的最長路,DP)
code head struct sin == cout article scanf for ?? 解題思路: 求有向無環圖上的最長路。簡單的動態規劃#include <iostream> #include <cstring> #include
HOJ 13845 Atomic Computer有向無環圖的動態規劃
-1 會有 bsp pre 但是 自帶 += 排列組合 開始 考慮任意一個數字,任何一個都會有奇怪的。。性質,就是一個可以保證不重復的方案——直接簡單粗暴的最高位加數字。。於是,如同上面的那個題:+1、-1、0 但是考慮到65536KB的標準內存限制,會得出一個奇怪的性質,
CSU 1804 - 有向無環圖 - [樹形DP]
其中 如果 init max 枚舉 time 包含 mod %d 題目鏈接:http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1804 Bobo 有一個 n 個點,m 條邊的有向無環圖(即對於任意點 v,不存在從點 v 開
c/c++ 有向無環圖 directed acycline graph
rect 如果 拓撲排序 type 第一個 ima 結構 alt lse c/c++ 有向無環圖 directed acycline graph 概念: 圖中點與點之間的線是有方向的,圖中不存在環。用鄰接表的方式,實現的圖。 名詞: 頂點的入度:到這個頂點的線的數量。 頂