1. 程式人生 > >HDU 4081Qin Shi Huang's National Road System(最小生成樹+最小瓶頸路)

HDU 4081Qin Shi Huang's National Road System(最小生成樹+最小瓶頸路)

continue ++ ng- ims cstring 題意 cost 圖的最小生成樹 span



題意:秦始皇要修路。把N個城市用N-1條邊連通。且他希望花費最小,可是這時候有一個多管閑事的道士出來說他有魔法能夠幫助秦始皇變成一條路。可是僅僅能變出一條。

可是。兩個人對修路的法案存在歧義,道士希望修路能夠給很多其它的百姓帶來福利。而秦始皇希望修路要盡量使花費小。最後,秦始皇拿出了一個公式A/B。A表示兩個城市的人數,B表示出了用魔法變出來的路外。最短的總距離。

如今要你求出A/B的最大值。

思路:枚舉連接哪兩個城市。由於這條邊是免費的。我們要求算上這條邊的最小生成樹。假設每次都求一次最小生成樹會超時,所以先跑一遍整個圖的最小生成樹。然後再預處理出這個mst上的隨意兩點之間路徑的最大值,由於加入免費邊時,去掉的就是這個最大邊。這樣一樣時間復雜度降為O(n*n)。

#include<cstdio>  
#include<cstring>  
#include<cmath>  
#include<cstdlib>  
#include<iostream>  
#include<algorithm>  
#include<vector>  
#include<map>  
#include<queue>  
#include<stack> 
#include<string>
#include<map> 
#include<set>
#define eps 1e-6 
#define LL long long  
using namespace std;  

const int maxn = 1050;
const int maxm = maxn*maxn;
//const int INF = 0x3f3f3f3f;
vector<int> G[maxn];
int vis[maxn];
int n, m, ple[maxn], x[maxn], y[maxn];
int u[maxm], v[maxm], p[maxn], r[maxm];
double w[maxm], W[maxn][maxn], maxcost[maxn][maxn];;
bool cmp(const int i, const int j) {
	return w[i] < w[j];
} 
int find(int x) {
	return p[x] == x ? x : p[x] = find(p[x]);
}
double Kruscal() {
	double ans = 0;
	for(int i = 0; i < n; i++) p[i] = i; //初始化並查集 
	for(int i = 0; i < m; i++) r[i] = i; //初始化邊序號
	sort(r, r+m, cmp);
	for(int i = 0; i < m; i++) {
		int e = r[i]; 
		int x = find(u[e]), y = find(v[e]);
		if(x != y) {
			ans += w[e];
			p[x] = y;
			G[u[e]].push_back(v[e]); G[v[e]].push_back(u[e]);
		}
	}
	return ans;
}
void init() {
	memset(vis, 0, sizeof(vis));
	for(int i = 0; i < n; i++) G[i].clear();
}
void dfs(int cur, int fa) {
	maxcost[cur][cur] = 0;
	if(fa != -1) {
		for(int i = 0; i < n; i++) if(vis[i]){
			maxcost[i][cur] = maxcost[cur][i] = max(maxcost[i][fa], W[fa][cur]);
		}
	}
	vis[cur] = 1;
	for(int i = 0; i < G[cur].size(); i++) {
		int u = G[cur][i];
		if(u == fa) continue;
		dfs(u, cur);
	}
}
int main() {
	//freopen("input.txt", "r", stdin);
	int T; cin >> T;
	while(T--) {
		cin >> n;
		for(int i = 0; i < n; i++) scanf("%d%d%d", &x[i], &y[i], &ple[i]);
		m = 0;
		for(int i = 0; i < n; i++) {
			for(int j = i+1; j < n; j++) {
				u[m] = i; v[m] = j;
				w[m] = sqrt((double)((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])));
				W[i][j] = W[j][i] = w[m];
				m++;
			}
		}
		init();
		double mst = Kruscal(); 
		//cout << mst << endl;
		dfs(0, -1);
		double ans = 0;
		for(int i = 0; i < n; i++) {
			for(int j = i+1; j < n; j++) {
				ans = max(ans, (double)(ple[i]+ple[j])/(mst-maxcost[i][j]));
			}
		}
		printf("%.2lf\n", ans);
	} 
	return 0;
}





HDU 4081Qin Shi Huang&#39;s National Road System(最小生成樹+最小瓶頸路)