比赛 HAOI2009 模拟试题1 评测结果 AWWWWEEEEE
题目名称 洞窟探索 最终得分 10
用户昵称 zqzas 运行时间 0.000 s
代码语言 C++ 内存使用 0.00 MiB
提交时间 2009-04-21 11:26:25
显示代码纯文本
#include <iostream>

using namespace std;

#define MAXN 155
#define MAXM 111
#define INF 99999999999LL

long long n,m,son[MAXN][3],data[MAXN][MAXN],F[MAXN][MAXM],A[MAXN][MAXM];
double ans;
bool vis[MAXN];

void dpF(int x,int i)
{
	if ((x==0 && i==0)|| i==0)
	{
		F[x][i]=0;
		return;
	}
	if (son[x][0]==0)
	{
		if (i==1)
			F[x][i]=0;
		else
		{
			F[x][i]=INF;
		}
		return;
	}
	int a,b,s1,s2,p1,p2,now;
	s1=son[x][0];s2=son[x][1];
	p1=data[x][s1];p2=data[x][s2];
	F[x][i]=INF;
	//put
	if (s2==0)
	{
		a=i-1;
		if (F[s1][a]==-1)
			dpF(s1,a);
		if (F[s1][a]!=INF)
		{
			if (F[s1][a]+(a)*p1<F[x][i])
				F[x][i]=F[s1][a]+(a)*p1;
		}
		return;
	}
	for (a=0;a<=i-1;a++)
	{
		b=i-a-1;
		if (F[s1][a]==-1)
			dpF(s1,a);
		if (F[s2][b]==-1)
			dpF(s2,b);
		if (F[s1][a]==INF || F[s2][b]==INF)
			continue;
		now=F[s1][a]+a*p1+F[s2][b]+(b)*p2;
		if (now<F[x][i])
			F[x][i]=now;
	}
	//not put
	if (s2==0)
	{
		a=i;
		if (F[s1][a]==-1)
			dpF(s1,a);
		if (F[s1][a]!=INF)
		{
			if (F[s1][a]+(a)*p1<F[x][i])
				F[x][i]=F[s1][a]+(a)*p1;
		}
		return;
	}
	for (a=0;a<=i;a++)
	{
		b=i-a;
		if (F[s1][a]==-1)
			dpF(s1,a);
		if (F[s2][b]==-1)
			dpF(s2,b);
		if (F[s1][a]==INF || F[s2][b]==INF)
			continue;
		now=F[s1][a]+a*p1+F[s2][b]+(b)*p2;
		if (now<F[x][i])
			F[x][i]=now;
	}
}

void dpA(int x,int i)
{
	if ((x==0 && i==0) || i==0)
	{
		A[x][i]=0;
		return;
	}
	if (son[x][0]==0)
	{
		if (i==1)
			A[x][i]=0;
		else
			A[x][i]=INF;
		return;
	}
	int a,b,s1,s2,p1,p2,now;
	s1=son[x][0];s2=son[x][1];
	p1=data[x][s1];p2=data[x][s2];
	A[x][i]=INF;
	//put
	if (s2==0)
	{
		a=i-1;
		if (A[s1][a]==-1)
			dpA(s1,a);
		if (A[s1][a]!=INF)
		{
			now=A[s1][a]+(i-a)*F[s1][a]+a*(i-a)*p1;
			if (now<A[x][i])
				A[x][i]=now;
			
		}
		return;
	}
	for (a=0;a<=i-1;a++)
	{
		b=i-a-1;
		if (A[s1][a]==-1)
			dpA(s1,a);
		if (A[s2][b]==-1)
			dpA(s2,b);
		if (A[s1][a]==INF || A[s2][b]==INF)
			continue;
		now=A[s1][a]+(i-a)*F[s1][a]+a*(i-a)*p1;
		now+=A[s2][b]+(i-b)*F[s2][b]+b*(i-b)*p2;
		if (now<A[x][i])
			A[x][i]=now;
	}
	//not put
	if (s2==0)
	{
		a=i;
		if (A[s1][a]==-1)
			dpA(s1,a);
		if (A[s1][a]!=INF)
		{
			now=A[s1][a]+(i-a)*F[s1][a]+a*(i-a)*p1;
			if (now<A[x][i])
				A[x][i]=now;
		}
		return;
	}
	for (a=0;a<=i;a++)
	{
		b=i-a;
		if (A[s1][a]==-1)
			dpA(s1,a);
		if (A[s2][b]==-1)
			dpA(s2,b);
		if (A[s1][a]==INF || A[s2][b]==INF)
			continue;
		now=A[s1][a]+(i-a)*F[s1][a]+a*(i-a)*p1;
		now+=A[s2][b]+(i-b)*F[s2][b]+b*(i-b)*p2;
		if (now<A[x][i])
			A[x][i]=now;
	}
}

void dfs(int x)
{
	int y,s=0;
	vis[x]=true;
	for (y=1;y<=n;y++)
		if (data[x][y]!=-1)
			if (!vis[y])
			{
				son[x][s++]=y;
				dfs(y);
			}
}

void run()
{
	double sum;
	dfs(1);
	dpF(1,m);
	dpA(1,m);
	sum=m*(m-1);
	sum/=2;
	ans=A[1][m]/sum;
}

void ini()
{
	int i,j,a,b,t;
	for (i=0;i<MAXN;i++)
		for (j=0;j<MAXN;j++)
		{
			data[i][j]=-1;
		}
	for (i=0;i<MAXN;i++)
		for (j=0;j<MAXM;j++)
			A[i][j]=F[i][j]=-1;
	cin>>n>>m;
	for (i=1;i<n;i++)
	{
		cin>>a>>b>>t;
		data[a][b]=data[b][a]=t;
	}
}

int main()
{
	freopen("hole.in","r",stdin);
	freopen("hole.out","w",stdout);
	ini();
	if (m<=1)
		ans=0;
	else
		run();
	printf("%.2lf",ans);
	return 0;
}