1.拓扑排序
public boolean Topology(int n, int[][] edges) {
List<Integer>[] g = new ArrayList[n];
Arrays.setAll(g, e -> new ArrayList<Integer>());
int[] count = new int[n];
for (int[] e : edges) {
int v = e[0], u = e[1]; //v是起始,u是终点
g[v].add(u);
count[u]++;
}
Queue<Integer> queue = new LinkedList<>();
for (int i = 0; i < n; i++) {
if (count[i] == 0) queue.add(i);
}
while (!queue.isEmpty()) {
int v = queue.poll();
for (int u : g[v]) {
count[u]--;
if (count[u] == 0) queue.add(u);
}
}
for (int num : count) {
if (num != 0) return false;
}
return true;
}
2.prim算法(堆优化)
public int prim(int n, int[][] edges) {
List<int[]>[] g = new ArrayList[n];
Arrays.setAll(g, e -> new ArrayList<int[]>());
for (int[] e : edges) {
int u = e[0], v = e[1], cnt = e[2];
g[u].add(new int[]{v, cnt});
g[v].add(new int[]{u, cnt});
}
HashSet<Integer> visited = new HashSet<>();
PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[1] - b[1]);
pq.offer(new int[]{0,0});
int res = 0;
while (visited.size() < n) {
int[] p = pq.poll();
if (visited.contains(p[0])) continue;
visited.add(p[0]);
res += p[1];
for (int[] u : g[p[0]]) {
if (u[0] != p[0]) {
pq.offer(u);
}
}
}
return res;
}
3.Kruskal算法
public int kruskal(int n, int[][] edges) {
UnionJoin unionJoin = new UnionJoin(n);
int res = 0;
for (int[] item : edges) {
if (unionJoin.union(item[0], item[1])) {
res += item[2];
}
}
return res;
}
class UnionJoin {
int[] parent;
public UnionJoin(int n) {
parent = new int[n];
for (int i=0; i<n; i++) {
parent[i] = i;
}
}
public boolean union(int i, int j) {
int parentI = getParent(i);
int parentJ = getParent(j);
if (parentI == parentJ) return false;
parent[parentI] = parentJ;
return true;
}
public int getParent(int i) {
if (parent[i] != i) parent[i] = getParent(parent[i]);
return parent[i];
}
}
4.dijkstra算法(堆优化)
public int[] research(int[][] edges, int n) {
List<int[]>[] g = new ArrayList[n];
Arrays.setAll(g, e -> new ArrayList<int[]>());
for (int[] e : edges) {
int u = e[0], v = e[1], cnt = e[2];
g[u].add(new int[]{v, cnt});
g[v].add(new int[]{u, cnt});
}
int[] dist = dijkstra(g, 0);
return dist;
}
private int[] dijkstra(List<int[]>[] g, int start) {
int[] dist = new int[g.length];
Arrays.fill(dist, Integer.MAX_VALUE);
dist[start] = 0;
PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[1] - b[1]);
pq.offer(new int[]{start, 0});
while (!pq.isEmpty()) {
int[] p = pq.poll();
int x = p[0], d = p[1];
if (d > dist[x]) continue;
for (int[] e :g[x]) {
int y = e[0];
int newDist = d + e[1];
if (newDist < dist[y]) {
dist[y] = newDist;
pq.offer(new int[]{y, newDist});
}
}
}
return dist;
}