HDU-1875 暢通工程再續 (最小生成樹)

暢通工程再續

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 32093    Accepted Submission(s): 10532


Problem Description
相信大家都聽說一個“百島湖”的地方吧,百島湖的居民生活在不同的小島中,當他們想去其他的小島時都要通過劃小船來實現。現在政府決定大力發展百島湖,發展首先要解決的問題當然是交通問題,政府決定實現百島湖的全暢通!經過考察小組RPRush對百島湖的情況充分了解後,決定在符合條件的小島間建上橋,所謂符合條件,就是2個小島之間的距離不能小於10米,也不能大於1000米。當然,爲了節省資金,只要求實現任意2個小島之間有路通即可。其中橋的價格爲 100元/米。
 

Input
輸入包括多組數據。輸入首先包括一個整數T(T <= 200),代表有T組數據。
每組數據首先是一個整數C(C <= 100),代表小島的個數,接下來是C組座標,代表每個小島的座標,這些座標都是 0 <= x, y <= 1000的整數。
 

Output
每組輸入數據輸出一行,代表建橋的最小花費,結果保留一位小數。如果無法實現工程以達到全部暢通,輸出”oh!”.
 

Sample Input
2 2 10 10 20 20 3 1 1 2 2 1000 1000
 

Sample Output
1414.2 oh!
#include <bits/stdc++.h>
using namespace std;
struct edge{
	int from, to, val;
	bool operator < (const edge& x) const{
		return val < x.val;
	}
}a[11111];
int p[11111], x[111], y[111];
int findset(int x){
	return p[x] == x ? x : p[x] = findset(p[x]);
}
int main(){
	int T;
	scanf("%d", &T);
	while(T--){
		int n, u, v, num;
		scanf("%d", &n);
		for(int i = 1; i <= n; ++i){
			scanf("%d %d", &x[i], &y[i]);
		}
		num = 0;
		for(int i = 1; i <= n; ++i){
			for(int j = i + 1; j <= n; ++j){
				a[++num].from = i;
				a[num].to = j;
				a[num].val = (x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]);
			}
		}
		for(int i = 1; i <= n; ++i){
			p[i] = i;
		}
		sort(a + 1, a + 1 + num);
		int tot = 1, pos = 1;
		double ans = 0;
		while(tot < n && pos <= num){
			u = findset(a[pos].from);
			v = findset(a[pos].to);
			if(u != v && a[pos].val <= 1000000 && a[pos].val >= 100){
				p[u] = v;
				tot++;
				ans += sqrt(a[pos].val);
			}
			pos++;
		}
		ans *= 100;
		if(tot < n){
			printf("oh!\n");
		}
		else{
			printf("%.1f\n", ans);
		}
	}
	
}

/*
題意:
100個城市,給出它們的座標,求最小生成樹。

思路:
最小生成樹裸題,並查集維護一下兩點的連通性。
*/


發佈了165 篇原創文章 · 獲贊 4 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章