hihocoder 最小生成樹二·Kruscal算法

時間限制:10000ms
單點時限:1000ms
內存限制:256MB

描述

隨着小Hi擁有城市數目的增加,在之間所使用的Prim算法已經無法繼續使用了——但是幸運的是,經過計算機的分析,小Hi已經篩選出了一些比較適合建造道路的路線,這個數量並沒有特別的大。

所以問題變成了——小Hi現在手上擁有N座城市,且已知其中一些城市間建造道路的費用,小Hi希望知道,最少花費多少就可以使得任意兩座城市都可以通過所建造的道路互相到達(假設有A、B、C三座城市,只需要在AB之間和BC之間建造道路,那麼AC之間也是可以通過這兩條道路連通的)。

提示:積累的好處在於可以可以隨時從自己的知識庫中提取想要的!

輸入

每個測試點(輸入文件)有且僅有一組測試數據。

在一組測試數據中:

第1行爲2個整數N、M,表示小Hi擁有的城市數量和小Hi篩選出路線的條數。

接下來的M行,每行描述一條路線,其中第i行爲3個整數N1_i, N2_i, V_i,分別表示這條路線的兩個端點和在這條路線上建造道路的費用。

對於100%的數據,滿足N<=10^5, M<=10^6,於任意i滿足1<=N1_i, N2_i<=N, N1_i≠N2_i, 1<=V_i<=10^3.

對於100%的數據,滿足一定存在一種方案,使得任意兩座城市都可以互相到達。

輸出

對於每組測試數據,輸出1個整數Ans,表示爲了使任意兩座城市都可以通過所建造的道路互相到達至少需要的建造費用。

代碼:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;

public class Main {
	public int kruscal(List<int[]> graph,int n){
		Collections.sort(graph,new Comparator<int[]>() {
			@Override
			public int compare(int[] o1, int[] o2) {
				return o1[2]-o2[2];
			}
		});
		int[] uf=new int[n+1];
		for(int i=0;i<uf.length;i++) uf[i]=i;
		int re=0;
		int num=0;
		for(int[] temp:graph){
			int ver0=temp[0];
			int ver1=temp[1];
			while(ver0!=uf[ver0]){
				uf[ver0]=uf[uf[ver0]];//這個很重要  hihocoder不這樣優化會超時
				ver0=uf[ver0];
			} 
			while(ver1!=uf[ver1]){
				uf[ver1]=uf[uf[ver1]];
				ver1=uf[ver1];
			} 
			if(ver0==ver1) continue;
			uf[ver1]=ver0;
			re+=temp[2];
			num++;
			if(num==n-1)break;
		}
		return re;
	}
	public static void main(String[] args) {
		Scanner scan=new Scanner(System.in);
		Main main=new Main();
		int vertexNum=scan.nextInt();
		List<int[]> graph=new ArrayList<int[]>();
		int num=scan.nextInt();
		for(int i=0;i<num;i++){
			int[] edge=new int[3];
			edge[0]=scan.nextInt();
			edge[1]=scan.nextInt();
			edge[2]=scan.nextInt();
			graph.add(edge);
		}
		System.out.println(main.kruscal(graph, vertexNum));
		
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章