為什麼要找樹的重心呢?假設我們已經找到了樹的重心,如果把開會地點從重心向右移走,那麼對答案的貢獻就是+左邊的元素和-右邊的元素和。而因為是樹的重心,所以向右移走後左面的元素數量一定大於右面的元素數量,所以ans是比在重心的情況大的,所以最終我們選擇重心。
#include#include#include
#include
#include
using
namespace
std;
const
int maxn=50005
;int
n,cnt,rt,maxp[maxn],ans,p[maxn],size[maxn];
struct
nodee[maxn*2
];void insert(int u,int
v)void getrt(int u,int
fa) maxp[u]=max(maxp[u],n-size[u]);
if(maxp[u]==maxp[rt]&&uu;
else
if(maxp[u]u;
}void dfs2(int u,int fa,int
deep)
}int
main()
maxp[
0]=0x3f3f3f3f
; getrt(
1,-1
); dfs2(rt,-1,0
); cout
<"
"
}
洛谷P1395 會議 題解
題目 為什麼這個題會有圖論的標籤啊,雖然圖論也包括找樹的重心,可是這很容易讓人聯想到最短路,但不得不說,這是乙個典型的找樹的重心模板題。樹的重心是什麼?找到乙個點,其所有的子樹中最大的子樹節點數最少,則這個點便是樹的重心。而我們找樹的重心該怎麼找呢,我們可以從定義入手,我們可以搜尋。我們先設任意乙個...
洛谷 P5666 樹的重心
關於樹的重心有一條性質,假如 u 不是重心,那麼重心一定在 u 的size最大的子樹中.利用這個性質我們可以利用倍增的思想快速找到重心.即維護 jump u,i 表示從 u 出發,向重兒子走 2 i 步所到達的節點.由於要對於每條邊統計,所以用換根dp的思想,在dfs的時候維護以當前節點為根時的 j...
P1395 會議(樹上找一點到所有點距離和最小)
題意 一顆n個點的樹,n 1條邊,每條邊的權值為1,找到乙個點,使得所有點到這個點的距離之和最小。思路 我們假設點1為根時,總花費為f 1 假設點2是點1的子節點,那麼f 2 f 1 點2的子節點個數 n 點2的子節點個數 因為我們把根從1換到2的時候,2的子樹中節點貢獻全部 1,其他節點貢獻全部 ...