- 最小生成树+并查集
D
e
s
c
r
i
p
t
i
o
n
\color{blue}{Description}
Description
某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。
I
n
p
u
t
\color{blue}{Input}
Input
测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( < 100 );随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1到N编号。
当N为0时,输入结束,该用例不被处理。
O
u
t
p
u
t
\color{blue}{Output}
Output
对每个测试用例,在1行里输出最小的公路总长度。
S
a
m
p
l
e
I
n
p
u
t
\color{blue}{Sample Input }
SampleInput
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
S
a
m
p
l
e
O
u
t
p
u
t
\color{blue}{Sample Output}
SampleOutput
3
5
H
i
n
t
\color{blue}{Hint}
Hint
Huge input, scanf is recommended.
import java.io.BufferedInputStream;
import java.util.PriorityQueue;
import java.util.Scanner;
public class Main{
/* [8.3~8.9]最小生成树
* */
static final int N=(int)5e5+10,M=N<<1;
static int []fa;
static int n;
public static void main(String[] args) {
Scanner sc=new Scanner(new BufferedInputStream(System.in));
int e,v,s,b;
while(true) {
n=sc.nextInt();
if(n==0) break;
PriorityQueue<node>q=new PriorityQueue<node>();
//记录边的信息
int len=n*(n-1)/2;
for(int i=1;i<=len;i++) {
s=sc.nextInt();
b=sc.nextInt();
v=sc.nextInt();
q.add(new node(s,b,v));
}
int sum=0;
fa=new int [n+1];
//并查集初始化。
for(int i=0;i<fa.length;i++) fa[i]=i;
//合并
while(!q.isEmpty()) {
node no=q.poll();
int l=find(no.s);
int r=find(no.e);
if(l!=r) {
fa[l]=r;
sum+=no.v;
}
}
System.out.println(sum);
}
}
static int find(int x) {
if(fa[x]==x) return x;
return (fa[x]=find(fa[x]));
}
static class node implements Comparable<node>{
int s,e,v;
public node(int s,int e,int v) {
this.s=s;this.e=e;this.v=v;
}
public int compareTo (node o) {
if(this.v>o.v) return 1;
else if(this.v==o.v) return 0;
return -1;
}
}
}