G - 还是畅通工程

  • 最小生成树+并查集

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;
		}
	}
}

你可能感兴趣的:(最小生成树)