演算法提高 最小方差生成樹

2021-08-11 16:50:49 字數 1490 閱讀 3841

問題描述

給定帶權無向圖,求出一顆方差最小的生成樹。

輸入格式

輸入多組測試資料。第一行為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 61 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

資料規模與約定

1<=u,v<=n<=50,n-1<=m<=1000,0<=w<=50。資料不超過5組。

方差公式:

m為平均值。也就是說我們要找出x1,x2,x3,xn 滿足這個公式。

但是平均值我們不知道。我們要假設。

可以二分,也可以列舉。

平均值的最小值就是最小的幾個邊,最大值就是最大的幾個邊。求出來for,對於每乙個平均值,

我們讓每個邊的值變成(val-平均值)2.

對這個新的值進行排序進行kruscal演算法即可。

不過求出來後要檢查一下選出來的這些邊的平均值是不是我們列舉的那個。如果是,在輸出

#include

#include

using namespace std;

double const max = 10000000000000.0;

int n, m, tmp[1005], fa[55];

double ans;

struct edge

e[1005];

bool cmp(edge a, edge b)

void uf_set(int n)

int find(int x)

void union(int a, int b)

void kruskal(int sum)

if(cnt == n - 1)

break;

}if((int)all == sum)

ans = min(ans, f_all);

}int main()

sort(tmp, tmp + m);

for(int i = 0; i < n - 1; i++)

minv += tmp[i];

for(int i = m - 1; i > m - n; i--)

maxv += tmp[i];

for(int i = minv; i <= maxv; i++)

kruskal(i);

ans = ans / (n - 1);

printf("case %d: %.2f\n", ca++, ans);}}

演算法提高 最小方差生成樹

演算法提高 最小方差生成樹 時間限制 1.0s 記憶體限制 256.0mb 問題描述 給定帶權無向圖,求出一顆方差最小的生成樹。輸入格式 輸入多組測試資料。第一行為n,m,依次是點數和邊數。接下來m行,每行三個整數u,v,w,代表連線u,v的邊,和權值w。保證圖連通。n m 0標誌著測試檔案的結束。...

bzoj 3754 Tree之最小方差樹

題目大意 給你乙個無相連通圖,要你找出乙個生成樹,使得他們的邊權的方差最小。n 100,m 2000,c 邊權 100 我們考慮最小生出樹常用的kruskal演算法,它需要得到乙個邊的排列,然後在進行貪心的加邊。我們可以考慮暴力每個排列,然後進行kruskal。這樣時間複雜度為o m m 我們發現複...

最小生成樹演算法

由帶權的連通圖生成的數的各邊加起來稱為生成樹的權,把權值最小的生成樹稱為最小生成樹 minimum spanning tree 簡稱為mst 構造最小生成樹的方法就是利用mst性質,一條一條地選擇可以加入的邊。下面介紹兩種用於構造最小生成樹的演算法,其中第一種演算法稱為prim演算法,第二種演算法稱...