hud 4081 次小生成樹應用

2021-08-15 02:16:45 字數 1670 閱讀 1599

這個題確實不簡單,難就難在對題意的正確的理解上,

題意;

秦始皇想要修路使得n個城市連通,同時使得這些路盡量短。這時徐福說他可以在2個城市之間不花費人力物力建一條路,但他只能建1條這樣的路。秦始皇想要使除了徐福造的那條路以外的路的總長度盡量短,而徐福想要造福更多的百姓,他想要使自己用法術建的那條路的兩端的城市的總人口數最多。最終二人達成協議。假設a=用法術建的那條路的兩端的城市的總人口數,b=除了徐福造的那條路以外的路的總長度,建造的路要使得a/b最大。輸出a/b。

咱們先來分析一下這個題,一開始以為是直接在最小生成樹上列舉邊就行,再仔細一想,不對啊,最小生成樹不唯一,這樣列舉肯定不對啊,再去讀題才明白,徐福建的這條路不一定是在最小生成樹上,只要滿足a / b 最大就可以,這樣就可以分為兩種情況

第一種情況是 如果這條邊在最小生成樹上的話,那直接就是 這條邊相連的城市的 人口之和 / mst - 邊權

第二種情況是 如果這條邊不在最小生成樹上的話,這種情況也是可以的,

原因是 只要 所連線的兩個城市的人口如果特別大的話,a / b ,也滿足題意。

那樣的話,mst 在加入一條邊就肯定成環,要使 a / b 最大,在a固定的情況下,b 最小就行啊,b = mst - 環中的邊,現在轉化成求這條最大的邊。就是最小瓶頸路了,

問題就這樣解決了,

#include

#include

#include

#include

#include

using

namespace

std;

struct city

;const

int maxn = 1010;

const

int max = 0x3f3f3f3f;

city city[maxn];

double _map[maxn][maxn];

double maxcost[maxn][maxn];

bool tag[maxn];

double dis[maxn];

bool used[maxn][maxn];

int father[maxn];

int n;

double f(city a,city b)

double prim()

tag[1] = 1;

father[1] = 0;// 遺漏

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

}if(now == max)

return -1;

ans += _min;

tag[now] = 1;

used[father[now]][now] = used[now][father[now]] = 1; // 錯誤

for(int j = 1;j <= n; ++j)}}

return ans;

}double smst()

}return ans;

}int main()

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

}double ans = smst();

cout

<< fixed << setprecision(2) << ans << endl;

}return

0;}

hdu 4081 次小生成樹

找到乙個生成樹,並且保證a b最大,所以b要盡量小,a盡量大。b盡量小,就要想到最小生成樹,但是最小生成樹裡面,可以刪除乙個邊,這樣就轉化為次小生成樹中找a b最大的情況。或者prim 並查集。include include include include include using namespa...

HDU 4081 次小生成樹變形

題意是有n個點,分別輸入n個點的座標和這個點的權值,然後要給這些點建邊,建邊的權值就是兩點間的距離,現在可以免費的建一條邊,求免費建邊的兩個點的權值和與總費用的最大值。思路就是模擬次小生成樹的思路,在刪邊的過程中維護所要求的最大值就好了。ac include define maxn 1005 def...

次小生成樹 配題(HDU 4081)

次小生成樹 在最小生成樹 mst 的基礎上求得。演算法步驟 配題 hdu 4081 題意 無向圖,有 n 個點,每個點的座標和該點具有的人口數告訴你,秦始皇想將n個點連通起來,用最小的代價去鋪路 總里程數最小 有乙個巫師,可以將一條路的代價將為 0 巫師選中的這條路必須被建造 求 一條路的乙個特殊比...