topological sort可用來檢測是否爲DAG(有向無環圖)
拓撲排序的兩種寫法:dfs和bfs
DFScode
public boolean dfs(List<Integer>[] graph, int i, int[] used) { if (used[i] == 1) return false; if (used[i] == 2) return true; used[i] = 1; for (int next : graph[i]) { if (!dfs(graph, next, used)) return false; } used[i] = 2; res.add(0, i); //topo路徑 return true; }
BFS排序
Queue<Integer> q = new LinkedList<>(); for (int i = 0; i < numCourses; i ++) { if (indegree[i] == 0) //入度爲0 q.offer(i); } List<Integer> res = new ArrayList<>(); while (!q.isEmpty()) { int cur = q.poll(); res.add(cur); // topo路徑 for (int next : graph[cur]) { if (--indegree[next] == 0) q.offer(next); } }
如何判斷topo路徑是否惟一:BFS,每次indegree爲0的節點僅有一個leetcode
class UF { int[] root; public UF(int n) { root = new int[n]; for (int i = 0; i < n; i ++) root[i] = i; } public boolean union(int i, int j) { int pi = find(i); int pj = find(j); if (pi == pj) return false; root[pi] = pj; return true; } public int find(int i) { if (i != root[i]) root[i] = find(root[i]); return root[i]; } }
可根據須要求連通份量個數,各聯通份量的大小
261. Graph Valid Tree
樹:無向聯通無環圖,dfs/topo都可解rem
Euler Path:每條邊都經過且僅經過一次的路徑
判斷圖中是否存在Euler Path:
(1)圖聯通且無孤立點
(2)無向圖:奇數點爲0或2
有向圖:不存在或僅存在兩個點的入度不等於出度
求Euler Path:get
void EulerPath(u) { for each edge e = (u, v) in E: remove(u, v) from E EulerPath(v) prepend u to path }