模擬賽 修路 題解 kruskal

2021-07-28 01:14:04 字數 1339 閱讀 6929

【問題描述】

在 b 國裡,有 n 個城市,每個城市有乙個發達程度 a[i]。b 要修建一些道路,

修建這條道路的花費為 cost[i],把這些城市連起來,使得任意 2 個城市之間,有

且只有 1 條路相聯通。最後這些道路建成時,每個城市對 b 國的經濟會做出貢

獻,貢獻度為 a[i] (i 這個城市它所直接相連的城市數)(但由於 b 國的人民隻熱

衷於翻牆,所以經濟並不發達,這個貢獻值會遠遠小於 cost)。

這樣 b 就得出了乙個對這個方案的代價,為總 cost-總貢獻值,現在 b 要求

一種方案使得這個代價最小。

【輸入格式】

第一行兩個數 n,m,表示城市數量,可以修建的道路條數 m。

接下來 1 行 n 個數,表示 a[i]。

接下來 m 行,每行 3 個數,x,y,z,表示一條從 x 到 y 的雙向邊,修這條路

的代價為 z。

【輸出格式】

乙個數表示最小代價。

【樣例輸入】

3 3

1 2 3

1 2 21

1 3 21

2 3 22

【樣例輸出】

34 【樣例解釋】

選邊 (1,3)和(2,3) , 代價為 21+22-(1*1+2*1+3*2)=34

【資料範圍】

30%的資料:n=1000;

100%的資料:n=100000,m=100000,0=a[i]=10, 20=z=2^31;

資料保證至少存在一組解。

【題目解釋】

給出n個點和m個邊,讓你用m-1條邊將n個點連起來,且費用最小。

【題目型別】

最小生成樹

【解題報告】

其實此題初看很難,但是仔細一想,每一條邊的權值其實就是z-a[x]-a[y](因為城市i的貢獻度為a[i],城市i每連一條邊就要減一次貢獻度,所以直接在邊權中減去就行了,處理起來很方便)。

【示例**】

#include

#include

#include

using

namespace

std;

const

int maxn=100005;

int n,m,tot,fa[maxn];

long

long ans,p[maxn];

struct wjd

int get_(int x)

int main()

printf("%lld",ans);

return

0;}

NOIP模擬 修路

這題第一眼看上去有些懵逼,還以為是dp。第二眼,哦,這麼裸的最小生成樹,2分鐘打完,拍都沒對,自信100分。最終100分。每條邊的權值減去連個節點的權值,所有的邊做一次最小生成樹就好了。include include include include include define fo i,a,b f...

模擬賽 circle 題解

題意 有n個數,問有多少個x,x leq t 滿足這n個數分別 x後,異或和為s。每個數小於 2 m 數字dp。由於是加法,需要記錄進製,因此從低位到高位dp。只要記錄下有幾個進製,就可以根據這n的數的大小知道究竟是哪幾個進製了。設 dp i,j,0 1 表示考慮到第i位,有j個進製,與t的大小關係...

模擬賽2 題解

這次模擬賽最後一道是提答題,就不寫題解了。orz這題 emmm,我無話可說。小範圍記憶化,大範圍遞迴求解 複雜度 o k sqrt 記 f i,j 表示前 j 個數中不被 a i,a dots,a n 整除的個數,答案即為 f 1,n 狀態轉移方程為 f i,j f i 1,j f i 1,j a ...