题目描述:
某省调查乡村交通情况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任意两个村庄之间都可以实现公路交通(但不一定有直接的公路相连,只要间接通过公路可达即可),并要求铺设的公路总长度最短。请计算最小的公路总长度。
输入:
测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N(<100);随后的N(N-1)/2行对应村庄之间的距离,每行给出一对正整数,分别是两个村庄的编号,以及两个村庄间的距离。为简单起见,村庄从1到N编号,当N为0时,输入结束,该用例不被处理。
输出:
对每个测试用例,在1行里输出最短的公路总长度。
样例输入:
3
1 2 1
1 3 2
2 3 4
4
1 2 1
1 3 4
1 4 1
2 3 3
2 4 2
3 4 5
0
样例输出:
3
5
示例代码:
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()){
int node_cnt = scanner.nextInt();
if (node_cnt==0){break;}
Node nodes = new Node(node_cnt);
int edge_cnt = node_cnt*(node_cnt-1)/2;
Edge[] edges=new Edge[edge_cnt+1];
for (int i=1;i<=edge_cnt;i++){
int firstvillage = scanner.nextInt();
int secondvillage = scanner.nextInt();
int weight = scanner.nextInt();
edges[i]=new Edge(firstvillage,secondvillage,weight);
}
//Kruskal算法生成MST
Arrays.sort(edges,1,edge_cnt,new cmp());
int length = 0;
for (int j=1;j<=edge_cnt;j++){
int fnode = edges[j].fnode;
int snode = edges[j].snode;
boolean isconnected = nodes.isConnected(fnode,snode);
if (isconnected){continue;}
else {
nodes.unionNodes(fnode,snode);
length+=edges[j].cost;
}
}
System.out.println(length);
}
}
}
/*
* 为全体结点创建一个类,包含每个结点的根结点和此结点的重量
* */
public class Node {
int[] nodes;//保存每个结点的根结点
int size;
int[] weights;//保存每个结点的重量,为将两个结点(集)合并提供依据
public Node(int size){
this.size = size;
nodes = new int[size+1];
weights = new int[size+1];
for (int i=1;i<=size;i++){
nodes[i] = i;
weights[i]=1;
}
}
public int findroot(int node){
if (node==nodes[node]){return node;}
else {
int root = findroot(nodes[node]);
nodes[node]=root;
return root;
}
}
public void unionNodes(int fnode,int snode){
int froot = findroot(fnode);
int sroot = findroot(snode);
if (froot==sroot){return;}
else {
int fweight = weights[froot];
int sweight = weights[sroot];
if (fweight<=sweight){nodes[froot]=sroot;weights[sroot]+=fweight;}
else{nodes[sroot]=froot;weights[froot]+=sweight;}
}
}
public boolean isConnected(int fnode,int snode){return findroot(fnode)==findroot(snode);}
public int setsNumber(int[] nodes){
int cnt=0;
for (int k=1;k<=size;k++){
if (nodes[k]==k){cnt++;}
}
return cnt;
}
}
/*
* 每条边为一个类,保存其权值和两个顶点
* */
public class Edge {
int fnode,snode;
int cost;
public Edge(int fnode,int snode,int cost){
this.fnode=fnode;
this.snode=snode;
this.cost=cost;
}
}
/*按照权值将边进行排序*/
import java.util.Comparator;
public class cmp implements Comparator<Edge> {
@Override
public int compare(Edge o1, Edge o2) {
if (o1.cost<o2.cost){return -1;}
else {return 1;}
}
}