Algoritmo prim para árbol de expansión mínimo
①. Título
②. Pensando
- Aquí está el gráfico denso, usando la matriz de adyacencia para el almacenamiento
Prim算法步骤
// Prim是更新不在集合中的点 离集合S的距离
//dist[i]距离设置为无穷大
dist[1]=0
for i in 0..n-1
//找到不在s集合中,距离s集合最近的点t
//将这个点t放入集合中
//利用这个点t, 更新不在集合中的点
dist[j] = min(dist[j], g[t][j])
③. Puntos de aprendizaje
普里姆算法_最小生成树
④. Implementación del código
import java.util.Scanner;
public class Main {
/*
* Prim是更新不在集合中的点 离集合S的距离
* dist[i]距离设置为无穷大
dist[1]=0
* for i in 0..n-1
找到不在s集合中,距离s集合最近的点t
将这个点t放入集合中
利用这个点t, 更新不在集合中的点
dist[j] = min(dist[j], g[t][j])
*/
static int N=510,INF=0x3f3f3f3f;
static int g[][]=new int[N][N];//邻接矩阵
static int dist[]=new int[N];//表示到集合的最短距离
static boolean st[]=new boolean[N]; //记忆化数组
static int n,m;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//初始化邻接矩阵和集合距离
for (int i = 0; i <N; i++) {
dist[i]=INF;
for (int j = 0; j <N; j++) {
//初始化邻接矩阵存储的最短距离
g[i][j]=INF;
}
}
n=sc.nextInt();m=sc.nextInt();
while(m-->0) {
int a=sc.nextInt(),b=sc.nextInt(),c=sc.nextInt();
//重边取最小值
g[a][b]=g[b][a]=Math.min(g[b][a], c);
}
int t=prim();
//有点不连通的时候,不存在最小生成树
System.out.println(t==INF?"impossible" :t);
}
static int prim() {
int ans=0;
for (int i = 0; i <n; i++) {
//遍历n个点
int t=-1;
for(int j=1;j<=n;j++) {
//找到一个最短边权的点
if(!st[j]&&(t==-1||dist[t]>dist[j])) {
t=j;
}
}
//不是第一个取出的节点,并且当前节点的距离为INF,则表示没有和集合中点相连的边。
if(i!=0&&dist[t]==INF) {
//没有和集合中点相连的边。直接impossible
return INF;
}
//写在前面,如果一个节点本身出现负环,下面这句更新后,会影响结果,
if(i!=0) {
//记录最小生成树的权值和
ans+=dist[t];
}
st[t]=true;
//更新当前最短边权点t到集合的距离(保留最小的值,如果比之前最短t到集合的距离还小,更新)
for (int j =1; j <=n; j++) {
dist[j]=Math.min(dist[j], g[t][j]);
}
}
return ans;
}
}