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 }