题意根本没看懂,通过此题熟悉了Kruskal算法和并查集思想。
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
import java.util.Scanner;
import java.util.Stack;
class Edge implements Comparable<Edge>//比较接口
{
int x;
int y;
int w;
Edge(int x,int y,int w){
this.x=x;
this.y=y;
this.w=w;
}
@Override
public int compareTo(Edge k) {
// TODO Auto-generated method stub
if(this.w==k.w) return 0;
return this.w-k.w;
}
}
public class Main1 {
static Scanner in=new Scanner(System.in);
static int pre[];
public static void main(String[] args) {
int n=in.nextInt();
int p=in.nextInt();
int px[]=new int[n+1];
Edge list[]=new Edge[p];
int min=px[1]=in.nextInt();
for(int i=2;i<=n;i++){
px[i]=in.nextInt();
if(min>px[i])
min=px[i];//寻找出最小的点值
}
int count=0;
for(int i=0;i<p;i++){
int x=in.nextInt();
int y=in.nextInt();
int w=in.nextInt();
list[i]=new Edge(x,y,w*2+px[x]+px[y]);
}
Arrays.sort(list);
pre=new int[n+1];
int ans=0;
for(int i=1;i<=n;i++){
pre[i]=i;
}
int x,y,tx,ty;
for(int i=0;i<list.length;i++){//Kruskal算法主体
x=list[i].x;
y=list[i].y;
tx=find(x);
ty=find(y);
if(tx!=ty){
count++;
ans+=list[i].w;
pre[tx]=ty;
if(count==n-1)//优化算法,找到即结束
break;
}
}
System.out.println(ans+min);
}
private static int find(int x) {//此处使用了并查集里的寻找根节点
return pre[x]==x?x:(pre[x]=find(pre[x]));
}
}