awson是某國際學校信競組的乙隻菜雞。終於弄明白邊權最小生成樹後,然而又被大神嘲笑了。大神深邃的眼光中透露了些睿智,說道:「你會求點權最小生成樹麼?」awson不屑的說道:「不會。但我有辦法。」於是他找到了你,請你幫他解決這個問題。
給你乙個有向連通圖g,每點有個權值di(0輸入格式:
第一行n,m分別為點數,邊數。(0<=n <= 20000;0<=m <= 200000)
接下來m行,每行兩個數u,v描述邊的兩個端點,即從u到v有一條有向邊。
最後一行n個數,順次給出每個點的權值。
輸出格式:
乙個數,最小代價。
輸入樣例#1:
5 4輸出樣例#1:1 21 3
3 43 5
1 2 3 4 5
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是否相等,...