prim算法基本题,贪心思想通过寻找子树和非子树点集之间的最短距离更新子树,因为每次都是保证最短,所以只需要控制子树端点即可。
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.StreamTokenizer ;
import java.io.IOException ;
public class Main{
private static int[][] map ;
private static int[] dist ;
public static void main(String arg[])throws IOException{
StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in))) ;
while(in.nextToken()!=StreamTokenizer.TT_EOF){
int N = (int)in.nval ;
if(N==0)break ;
int T = N*(N-1)/2 ;
map = new int[N+2][N+2] ;
while(T-->0){
in.nextToken() ;
int a = (int)in.nval ;
in.nextToken() ;
int b = (int)in.nval ;
in.nextToken() ;
int d = (int)in.nval ;
map[a][b] = d ;
map[b][a] = d ;
}
dist = new int[N+2] ;
for(int i=1;i<=N;i++) {
dist[i] = map[1][i];
}
int sum = 0 ;
int flag = 0 ;
boolean[] vis = new boolean[N+2] ;
for(int i=1;i<=N;i++){
int min = Integer.MAX_VALUE ;
for(int j=1;j<=N;j++){
//贪心思想寻找子树端点与非子树的点集的最短距离
if(dist[j]<min&&!vis[j]){
//更新两集合之间的最短距离
min = dist[j] ;
//更新待更新的子树端点
flag = j ;
}
}
sum += min ;
//更新之前先把这个子树端点设置为访问,访问后的点会成为子树除端点的一部分,因此不再访问
vis[flag] = true ;
//更新子树(实际上是更新子树端点)
for(int j=1;j<=N;j++){
if(!vis[j]&&map[flag][j]<dist[j]){
dist[j] = map[flag][j] ;
}
}
}
System.out.println(sum) ;
}
}
}