程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> HDU 4081 Qin Shi Huang's National Road System 次小生成樹

HDU 4081 Qin Shi Huang's National Road System 次小生成樹

編輯:C++入門知識

HDU 4081 Qin Shi Huang's National Road System 次小生成樹


給你n個城市 每個城市有一定數量的人 連接2個城市需要的花費是他們之間的距離 現在要建一顆最小生成樹 可以免費建其中一條邊 設A為免費的那條邊連接的2個城市的人口之和 B為修建的最小生成樹的花費 求最大的A/B

先求最小生成樹 設總花費為totol 然後可以枚舉免費的那條邊 枚舉邊等於A確定 在這條在最小生成樹裡的情況下 求最小的B

如果這條邊是最小生成樹裡的邊 那麼很容易求得B 拿totol減去這條邊就行了

如果不是 那麼把這條邊加到最小生成樹 會出現一個環 找到這個環最大的那條邊剪掉 就是次小生成樹的做法 然後類似求A/B

n^2預處理任意2點之間唯一路徑上的最大邊權

#include 
#include 
#include 
#include 
#include 
using namespace std;
const int maxn = 1010;

struct poit
{
	double x, y, p;
}p[maxn];
struct edge
{
	double dis;
	int u, v, next;
	bool select;
}e[maxn*maxn], G[maxn*2];

struct node
{
	double dis;
	int u, v;
	node(){}
	node(int u, int v, double d): u(u), v(v), dis(d) {}
};
int n;
double dp[maxn][maxn], totol;
int f[maxn];
int first[maxn], cnt;

void AddEdge(int u, int v, double w)
{
	G[cnt].u = u;
	G[cnt].v = v;
	G[cnt].dis = w;
	G[cnt].next = first[u];
	first[u] = cnt++;
	G[cnt].u = v;
	G[cnt].v = u;
	G[cnt].dis = w;
	G[cnt].next = first[v];
	first[v] = cnt++;
}
void init()
{
	for(int i = 1; i <= n; i++)
		f[i] = i;
	totol = 0;
	memset(dp, 0, sizeof(dp));
	memset(first, -1, sizeof(first));
	cnt = 0;
}

int find(int x)
{
	if(x != f[x])
		return f[x] = find(f[x]);
	return f[x];
}
double Dist(int i, int j)
{
	return sqrt((double)(p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y));
}

bool cmp(edge a, edge b)
{
	return a.dis < b.dis;
}
void MST(int l)
{
	for(int i = 0; i < l; i++)
	{
		int x = find(e[i].u);
		int y = find(e[i].v);
		if(x != y)
		{
			totol += e[i].dis;
			f[x] = y;
			e[i].select = true; 
			AddEdge(e[i].u, e[i].v, e[i].dis);
		}
	}
}
void BFS(int x)
{
	queue  Q;
	Q.push(node(-1, x, 0));
	while(!Q.empty())
	{
		node u = Q.front(); Q.pop();
		for(int i = first[u.v]; i != -1; i = G[i].next)
		{
			if(G[i].v == u.u)
				continue;
			double temp = max(u.dis, G[i].dis);
			dp[x][G[i].v] = max(dp[x][G[i].v], temp);
			Q.push(node(u.v, G[i].v, temp));
		}
	}
}
int main()
{
	int T;
	scanf("%d", &T);
	while(T--)
	{
		scanf("%d", &n);
		init();
		for(int i = 1; i <= n; i++)
			scanf("%lf %lf %lf", &p[i].x, &p[i].y, &p[i].p);
		int l = 0;
		for(int i = 1; i <= n; i++)
		{
			for(int j = i+1; j <= n; j++)
			{
				if(i == j)
					continue;
				e[l].u = i;
				e[l].v = j;
				e[l].select = false;
				e[l].dis = Dist(i, j);
				l++;
			}
		}
		sort(e, e+l, cmp);
		MST(l);
		
		for(int i = 1; i <= n; i++)
			BFS(i);
		double ans = 0.0;
		
		for(int i = 0; i < l; i++)
		{
			int u = e[i].u, v = e[i].v;
			if(e[i].select)
			{
				double tmp = (p[u].p + p[v].p) / (totol-e[i].dis);
				ans = max(ans, tmp);
			}
			else
			{
				
				double tmp = (p[u].p + p[v].p) / (totol-dp[u][v]);
				ans = max(ans, tmp);
			}
		}
		printf("%.2lf\n", ans);
	}
	return 0;
}


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved