darkBZOJ3080最小方差生成树

BZOJ权限题

Description:


求一个图的最小方差生成树。(1<=U,V<=N<=50,N-1<=M<=1000,0<=W<=50)

Analysis:

枚举平均值(精确到0.01)

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 60,M = 1100;
struct edge{
	int u,v;
	double w;
	bool operator < (const edge &a) const {
		return w < a.w;
	}
}e[M << 1],e1[M << 1];
int f[N],n,m,cnt;
double ave,ans;
int find(int p)
{
	if(f[p] == p) return p;
	return f[p] = find(f[p]);
}
void Merge(int a,int b)
{
	a = find(a);
	b = find(b);
	if(rand()%2 == 1) f[a] = b;
	else f[b] = a;
}
void kruscal()
{
	for(int i = 1;i <= m;++i)
	{
		e1[i].u = e[i].u;
		e1[i].v = e[i].v;
		e1[i].w = (e[i].w - ave)*(e[i].w - ave);
	}
	sort(e1+1,e1+1+m);
	double crt = 0;
	for(int i = 1;i <= n;++i) f[i] = i;
	for(int i = 1;i <= m;++i)
	{
		int u = find(e1[i].u),v = find(e1[i].v);
		if(u != v)
		{
			Merge(u,v);
			crt += e1[i].w;
		}
	}
	//printf("%.2lf
",crt);
	ans = min(crt,ans);
}
int main()
{
	while(~scanf("%d%d",&n,&m))
	{
		if(n == 0) break;
		cnt++;
		for(int i = 1;i <= m;++i)
		{
			scanf("%d%d%lf",&e[i].u,&e[i].v,&e[i].w);	
		}
		ans = 23333333.233;
		for(ave = 0.00;ave <= 50;ave += 0.01)
		{
			kruscal();
		}
		printf("Case %d: %.2lf
",cnt,ans/(n-1));
	}
	return 0;
}

岂能尽如人意,但求无愧我心
原文地址:https://www.cnblogs.com/Zforw/p/11378958.html