算法提高 最小方差生成树
时间限制:1.0s 内存限制:256.0MB
问题描述
给定带权无向图,求出一颗方差最小的生成树。
输入格式
输入多组测试数据。第一行为N,M,依次是点数和边数。接下来M行,每行三个整数U,V,W,代表连接U,V的边,和权值W。保证图连通。n=m=0标志着测试文件的结束。
输出格式
对于每组数据,输出最小方差,四舍五入到0.01。输出格式按照样例。
样例输入
4 5
1 2 1
2 3 2
3 4 2
4 1 1
2 4 3
4 6
1 2 1
2 3 2
3 4 3
4 1 1
2 4 3
1 3 3
0 0
1 2 1
2 3 2
3 4 2
4 1 1
2 4 3
4 6
1 2 1
2 3 2
3 4 3
4 1 1
2 4 3
1 3 3
0 0
样例输出
Case 1: 0.22
Case 2: 0.00
Case 2: 0.00
数据规模与约定
1<=U,V<=N<=50,N-1<=M<=1000,0<=W<=50。数据不超过5组。
#define _CRT_SECURE_NO_DEPRECATE #include<iostream> #include<cstdio> #include<algorithm> #define MAX 120 #define INF 1000000.0 using namespace std; double cost[MAX][MAX]; int N, M; double d[MAX]; bool visit[MAX]; double meanvalue, meanvarience;//顶点数、边数、最小平均值、最小方差值 void dfs(int x, int num){ if (num == N){ double value = 0, varience = 0;//平均值和方差 for (int i = 1; i < N; i++){ value += d[i]; } value /= (N - 1); for (int i = 1; i < N; i++){ varience += (d[i] - value)*(d[i] - value); } varience /= (N - 1); if (varience < meanvarience){ meanvarience = varience; } return; } for (int i = 1; i <= N; i++){ if (!visit[i] && cost[x][i] < INF){ visit[i] = true; d[num] = cost[x][i]; dfs(i, num + 1); visit[i] = false; } } } int main() { int u, v, t=0; double w; while (true){ scanf("%d %d", &N, &M); if (N + M == 0)break; for (int i = 1; i <= N; i++){ visit[i] = false; for (int j = 1; j <= N; j++){ cost[i][j] = INF; } } meanvalue = INF; meanvarience = INF; for (int i = 0; i < M; i++){ scanf("%d %d %lf", &u, &v, &w); if (cost[u][v]>w){ cost[u][v] = cost[v][u] = w; } } visit[1] = true; dfs(1, 1); printf("Case %d: %.2lf ", ++t, meanvarience); } return 0; }