面试常规算法复习(最小生成树)
两种常规的算法。
package com.company;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;
class Edge {
int a, b, w;
Edge(int a, int b, int w){
this.a = a;
this.b = b;
this.w = w;
}
}
public class Main {
public static void main(String[] args) {
int w[][] = new int[1005][1005];
int INF = 0x3f3f3f3f;
// System.out.println(INF);
int n, m;
Scanner in = new Scanner(System.in);
n = in.nextInt();
m = in.nextInt();
for (int i = 1; i <= n; i++){
for (int j = 1; j <= n; j++)
if (i != j)w[i][j] = INF;
else w[i][j] = 0;
}
for (int i = 1; i <= m; i++){
int u, v, W;
u = in.nextInt();
v = in.nextInt();
W = in.nextInt();
w[u][v] = Math.min(w[u][v], W);
w[v][u] = Math.min(w[v][u], W);
}
// int s = in.nextInt();
// int e = in.nextInt();
// kruskal(n, w);
prime(n, w);
}
public static int finds(int n, int f[]){
return f[n] == n?n:(f[n] = finds(f[n], f));
}
//将所有的边排序,从最小的边开始,将两点加入集合,如果在同一集合那么就不记录
//集合通过并查集维护
public static void kruskal(int n, int w[][]){
int INF = 0x3f3f3f3f;
Comparator<Edge> comparator = new Comparator<Edge>() {
@Override
public int compare(Edge o1, Edge o2) {
return o1.w-o2.w;
}
};
Queue<Edge> q = new PriorityQueue<Edge>(comparator);
for (int i = 1; i <= n; i++){
for (int j = i+1; j <= n; j++){
if (w[i][j] != INF){
q.add(new Edge(i, j, w[i][j]));
}
}
}
int f[] = new int[1005];
for (int i = 1; i <= n; i++){
f[i] = i;
}
int sum = 0;
while (!q.isEmpty()){
Edge x = q.poll();
int a = finds(x.a, f);
int b = finds(x.b, f);
if (a != b){
f[a] = b;
sum += x.w;
}
}
System.out.println(sum);
}
//思想类似与迪杰斯特拉算法。。。
//选择一个开始点,选择与开始点最短距离的点,将其连接记录,后面重复上次操作就可以了。
//注意在那个距离更新不是松弛操作。
public static void prime(int n, int w[][]){
int d[] = new int[1005];
boolean vis[] = new boolean[1005];
int INF = 0x3f3f3f3f;
for(int i = 1; i <= n; i++)d[i] = (i==1)?0:INF;
int sum = 0;
for(int i = 1; i <= n; i++){
int x=1, m=INF;
for(int j = 1; j <= n; j++){
if(!vis[j] && m > d[j]){
x = j;
m = d[j];
}
}
vis[x] = true;
sum += m;
// System.out.println(m);
for (int j = 1; j <= n; j++){
if (!vis[j])d[j] = Math.min(d[j], w[j][x]);
}
}
System.out.println(sum);
}
}