比赛 HAOI2009 模拟试题1 评测结果 AAAAAAWWWW
题目名称 洞窟探索 最终得分 60
用户昵称 王者自由 运行时间 0.000 s
代码语言 C++ 内存使用 0.00 MiB
提交时间 2011-03-25 20:44:48
显示代码纯文本
#include <cstdio>
#define MAXN 1502
#define MAXM 1002
#define INF 1<<29
int l[MAXN], r[MAXN], s[MAXN];
int F[MAXN][MAXM];
int a[MAXN][MAXN];
bool v[MAXN];
int n, m;
void BuildTree(int i) {
	if(s[i]>0)
		return;
	s[i] = 1;
	v[i] = true;
	for(int j=2; j<=n; j++)
		if(a[i][j]>0 && !v[j]) {
			if(l[i]==0)
				l[i] = j;
			else
				r[i] = j;
			BuildTree(j);
			s[i] += s[j];
			if(r[i]!=0)
				return;
		}
}
void DFS(int i, int j) {
	if(l[i]==0 || j<=1 || F[i][j]!=0)
		return;
	if(r[i]==0) {
		DFS(l[i], j-1);
		F[i][j] = F[i][j] + a[i][l[i]]*(j-1)*(m-j+1);
		F[i][j] = F[i][j] + F[l[i]][j-1];
	} else {
		int g;
		F[i][j] = INF;
		for(int k=0; k<=s[l[i]]; k++)
			if(j-1-k<=s[r[i]]) {
				if(k>j-1)
					break;
				DFS(l[i], k);
				DFS(r[i], j-1-k);
				g = a[i][l[i]]*k*(m-k)
					+ a[i][r[i]]*(j-1-k)*(m+k+1-j)
					+ F[l[i]][k] + F[r[i]][j-1-k];
				if(F[i][j]>g)
					F[i][j] = g;
			}
	}
}
int main() {
	freopen("hole.in","r",stdin);
	freopen("hole.out","w",stdout);
	scanf("%d %d", &n, &m);
	int x, y ,k;
	for(int i=1; i<n; i++) {
		scanf("%d %d %d", &x, &y, &k);
		a[x][y] = a[y][x] = k;
	}
	BuildTree(1);
	DFS(1, m);
	double sum = (double)m*(m-1)/2;
	double ans = F[1][m]/sum;
	printf("%.2lf\n", ans);
	return 0;
}