题目描述
使用Prim算法求图的最小生成树(MST)
输入
每组数据分为两个部分,第一部分为图的点数n,和边数m,
第二部分为m行,每一行输入三个数字,前两个为两个顶点的编号,第三个为边权重。
输出
最小生成树,输出时按照边的两个端点的升序输出。(先看左端点,再看右端点,端点不换位置)
样例输入 Copy
3 3
0 1 10
0 2 15
1 2 50
样例输出 Copy
0 1 10
0 2 15
package book;
import java.util.Scanner;
public class Prim {
static int m,n;
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc=new Scanner(System.in);
n=sc.nextInt();
m=sc.nextInt();
int map[][]=new int[m][m];
for(int i=0;i<m;i++) {
for(int j=0;j<m;j++) {
map[i][j]=Integer.MAX_VALUE;
}
}
for(int i=0;i<m;i++) {
int start=sc.nextInt();
int end=sc.nextInt();
int length=sc.nextInt();
map[start][end]=length;
map[end][start]=length;
}
slove(map);
}
private static void slove(int[][] map) {
int used[]=new int[n];
int closet[]=new int[n];
int lowcost[]=new int[n];
for(int i=1;i<n;i++) {
lowcost[i]=map[0][i];
closet[i]=0;//初始化
used[i]=0;
}
used[0]=1;
for(int i=1;i<n;i++) {
int j=0;
int min=Integer.MAX_VALUE;
for(int k=1;k<n;k++) {
if(lowcost[k]<min&&used[k]==0) {
min=lowcost[k];
j=k;
}
}
if(closet[j]<j) {
System.out.println(closet[j]+" "+j+" "+map[closet[j]][j]);
}
else {
System.out.println(j+" "+closet[j]+" "+map[closet[j]][j]);
}
used[j]=1;
for(int k=1;k<n;k++) {
if(map[j][k]<lowcost[k]&&used[k]==0) {
lowcost[k]=map[j][k];
closet[k]=j;
}
}
}
for(int j=1;j<n;j++) {
System.out.print(lowcost[j]+" ");
}
}
}