點權生成樹 gentree

2022-05-11 01:00:09 字數 1424 閱讀 7901

awson是某國際學校信競組的乙隻菜雞。終於弄明白邊權最小生成樹後,然而又被大神嘲笑了。大神深邃的眼光中透露了些睿智,說道:「你會求點權最小生成樹麼?」awson不屑的說道:「不會。但我有辦法。」於是他找到了你,請你幫他解決這個問題。

給你乙個有向連通圖g,每點有個權值di(0輸入格式:

第一行n,m分別為點數,邊數。(0<=n <= 20000;0<=m <= 200000)

接下來m行,每行兩個數u,v描述邊的兩個端點,即從u到v有一條有向邊。

最後一行n個數,順次給出每個點的權值。

輸出格式:

乙個數,最小代價。

輸入樣例#1:

5 4

1 21 3

3 43 5

1 2 3 4 5

輸出樣例#1:

23
樣例解釋:

如圖只有一種生成樹的方法,求得代價為23。

資料規模:

所有資料保證不會超過長整型(c++中的int)。

題解:

歸納發現,算出的總代價就是每個節點在生成樹中的深度×點權的和。

我們用貪心的思想,每個點的深度都要盡可能小。那麼我們只需以1號節點為源點,跑一遍最短路即可。

由最小生成樹的思想,我們易知所有求出的最短路徑都在一棵生成樹上,滿足題意。

#include#include

#include

#include

#include

#include

#include

using

namespace

std;

int n,m,ans,a[20001

];int head[20001],size=1

;struct

node

edge[

400005

];void putin(int

from,int

to)int dist[20001

];bool vis[20001

];void spfa(int

r) }}}

}int

main()

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

scanf("%d

",&a[i]);

spfa(1);

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

ans+=a[i]*dist[i];

printf(

"%d\n

",ans);

return0;

}

樹鏈剖分邊權轉化為點權

現在給出將樹鏈剖分上的邊權轉化為點權的方法 也就是將邊權轉到它下方的點去 我們通過畫圖可以發現,這樣的話,我們會多算最近公共祖先上方的點 方法一 先不考慮的多算的部分,還按原來的方法來,在之後消除最近公共祖先的影響 我們只需要在原來的 基礎上將 query path 改成 long long que...

Poj3237 樹刨 線段樹 邊權轉點權

題意 在樹上操作,每次將兩點路徑值全變負和單點修改。每次求兩點間路徑的最大值。思路 邊權轉點權的話,每次把一條邊的兒子點作為該邊的權值。想起來挺好想,很容易出問題。查詢修改的話,要將多算的那條lca去掉就可以了。剩下的就是板子。總結 去掉lca,只需要判斷top x top y 時,x和y是否相等,...

Poj3237 樹刨 線段樹 邊權轉點權

題意 在樹上操作,每次將兩點路徑值全變負和單點修改。每次求兩點間路徑的最大值。思路 邊權轉點權的話,每次把一條邊的兒子點作為該邊的權值。想起來挺好想,很容易出問題。查詢修改的話,要將多算的那條lca去掉就可以了。剩下的就是板子。總結 去掉lca,只需要判斷top x top y 時,x和y是否相等,...