import java.util.*;
public class Main {
// 有向图
static List<List<Integer>> buildGraph(int n, int[][] edges) {
List<List<Integer>> graph = new ArrayList<>();
for (int i = 0; i < n; i++) graph.add(new ArrayList<>());
for (int[] e : edges) {
graph.get(e[0]).add(e[1]);
}
return graph;
}
public static void main(String[] args) {
int n = 5;
int[][] edges = {{0,1},{0,3},{1,2},{1,4},{3,4}};
List<List<Integer>> g = buildGraph(n, edges);
for (int i = 0; i < n; i++) {
System.out.println(i + ": " + g.get(i));
}
}
}
步骤 2:图的 BFS 遍历
import java.util.*;
public class Main {
public static List<Integer> bfs(List<List<Integer>> graph, int start) {
List<Integer> res = new ArrayList<>();
Queue<Integer> queue = new LinkedList<>();
boolean[] visited = new boolean[graph.size()];
queue.offer(start);
visited[start] = true;
while (!queue.isEmpty()) {
int u = queue.poll();
res.add(u);
for (int v : graph.get(u)) {
if (!visited[v]) {
visited[v] = true;
queue.offer(v);
}
}
}
return res;
}
public static void main(String[] args) {
int n = 5;
int[][] edges = {{0,1},{0,3},{1,2},{1,4},{3,4}};
List<List<Integer>> g = buildGraph(n, edges);
System.out.println(bfs(g, 0)); // [0, 1, 3, 2, 4]
}
static List<List<Integer>> buildGraph(int n, int[][] edges) {
List<List<Integer>> g = new ArrayList<>();
for (int i = 0; i < n; i++) g.add(new ArrayList<>());
for (int[] e : edges) g.get(e[0]).add(e[1]);
return g;
}
}
步骤 3:图的 DFS 遍历
import java.util.*;
public class Main {
public static List<Integer> dfs(List<List<Integer>> graph, int start) {
List<Integer> res = new ArrayList<>();
boolean[] visited = new boolean[graph.size()];
Stack<Integer> stack = new Stack<>();
stack.push(start);
while (!stack.isEmpty()) {
int u = stack.pop();
if (visited[u]) continue;
visited[u] = true;
res.add(u);
// 注意:倒序入栈保证正序输出
List<Integer> neighbors = graph.get(u);
for (int i = neighbors.size() - 1; i >= 0; i--) {
int v = neighbors.get(i);
if (!visited[v]) stack.push(v);
}
}
return res;
}
public static void main(String[] args) {
int n = 5;
int[][] edges = {{0,1},{0,3},{1,2},{1,4},{3,4}};
List<List<Integer>> g = buildGraph(n, edges);
System.out.println(dfs(g, 0)); // [0, 1, 2, 4, 3]
}
static List<List<Integer>> buildGraph(int n, int[][] edges) {
List<List<Integer>> g = new ArrayList<>();
for (int i = 0; i < n; i++) g.add(new ArrayList<>());
for (int[] e : edges) g.get(e[0]).add(e[1]);
return g;
}
}
步骤 4:拓扑排序(Kahn 算法)
import java.util.*;
public class Main {
public static List<Integer> topoSort(int n, int[][] edges) {
List<List<Integer>> graph = new ArrayList<>();
int[] inDegree = new int[n];
for (int i = 0; i < n; i++) graph.add(new ArrayList<>());
for (int[] e : edges) {
graph.get(e[0]).add(e[1]);
inDegree[e[1]]++;
}
Queue<Integer> queue = new LinkedList<>();
for (int i = 0; i < n; i++) {
if (inDegree[i] == 0) queue.offer(i);
}
List<Integer> res = new ArrayList<>();
while (!queue.isEmpty()) {
int u = queue.poll();
res.add(u);
for (int v : graph.get(u)) {
inDegree[v]--;
if (inDegree[v] == 0) queue.offer(v);
}
}
return res.size() == n ? res : Collections.emptyList(); // 有环时返回空
}
public static void main(String[] args) {
int[][] edges = {{0,1},{1,2},{0,2},{2,3},{3,4}};
System.out.println(topoSort(5, edges)); // [0, 1, 2, 3, 4]
int[][] cycle = {{0,1},{1,2},{2,0}};
System.out.println(topoSort(3, cycle)); // []
}
}
步骤 5:Dijkstra 最短路
import java.util.*;
public class Main {
static class Edge {
int to, weight;
Edge(int t, int w) { to = t; weight = w; }
}
static class Node {
int dist, id;
Node(int d, int i) { dist = d; id = i; }
}
public static int[] dijkstra(int n, List<List<Edge>> graph, int start) {
int[] dist = new int[n];
Arrays.fill(dist, Integer.MAX_VALUE);
dist[start] = 0;
PriorityQueue<Node> pq = new PriorityQueue<>(Comparator.comparingInt(a -> a.dist));
pq.offer(new Node(0, start));
while (!pq.isEmpty()) {
Node cur = pq.poll();
if (cur.dist > dist[cur.id]) continue;
for (Edge e : graph.get(cur.id)) {
if (dist[cur.id] + e.weight < dist[e.to]) {
dist[e.to] = dist[cur.id] + e.weight;
pq.offer(new Node(dist[e.to], e.to));
}
}
}
return dist;
}
public static void main(String[] args) {
int n = 5;
List<List<Edge>> g = new ArrayList<>();
for (int i = 0; i < n; i++) g.add(new ArrayList<>());
g.get(0).add(new Edge(1, 4));
g.get(0).add(new Edge(2, 1));
g.get(1).add(new Edge(3, 1));
g.get(2).add(new Edge(1, 2));
g.get(2).add(new Edge(3, 5));
g.get(3).add(new Edge(4, 3));
int[] dist = dijkstra(n, g, 0);
System.out.println(Arrays.toString(dist)); // [0, 3, 1, 4, 7]
}
}