51nod 配對(求樹的重心)

2022-05-03 22:00:09 字數 1710 閱讀 5133

傳送門:

給出一棵n個點的樹,將這n個點兩兩配對,求所有可行的方案中配對兩點間的距離的總和最大為多少。

input

乙個數n(1<=n<=100,000,n保證為偶數)

接下來n-1行每行三個數x,y,z表示有一條長度為z的邊連線x和y(0<=z<=1,000,000,000)

output

乙個數表示答案
input示例

6

1 2 1

1 3 1

1 4 1

3 5 1

4 6 1

output示例

7

//配對方案為(1,2)(3,4)(5,6)

樹的重心。對於這題,配對的兩點的路徑一定要經過重心,這樣才能保證距離最大,而如果任意兩點都經過重心,他們的總距離一定是重心到其他點的距離和。這個模擬一下就能知道了。通過這題順帶學習一下樹的重心。

#include #include 

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define x first

#define y second

#define clr(u,v); memset(u,v,sizeof(u));

#define in() freopen("data","r",stdin);

#define out() freopen("ans","w",stdout);

#define clear(q); while (!q.empty()) q.pop();

#define pb push_back

using

namespace

std;

typedef

long

long

ll;typedef pair

pii;

const

int maxn = 1e5 + 10

;const

int inf = 0x3f3f3f3f

;struct

edge

e[2*maxn];

inthead[maxn], cnt, n, sz, pos;

intvis[maxn], sum[maxn];

ll dis[maxn];

ll ans = 0

;void

init()

void addedge(int v, int

u, ll w)

void dfs(int cur)//

求樹的重心

temp = max(temp, n - sum[cur] - 1

);//無向樹還要考慮上半部分

if (temp }void solve(int cur)//

算距離}

intmain()

dfs(1);

clr(vis, 0);

//cout << sz << " " << pos << endl;

solve(pos);

cout

<< ans

}

51nod 1737 樹的重心

思路 樹的重心也叫樹的質心。找到乙個點,其所有的子樹中最大的子樹節點數最少,那麼這個點就是這棵樹的重心,刪去重心後,生成的多棵樹盡可能平衡。考慮每一條邊被統計進答案幾次,若斷開這條邊後樹形成大小為s1 s2的兩個聯通塊則這條邊最多被統計min s1,s2 次。刪去重心後任意同一聯通塊中的兩點不構成路...

51nod 1737 思維 樹重心

思路 對於每一條邊,我們如果想要使得他發揮最大價值,其實就是這條邊被用了 min sonsz u sonsz v 次,那麼我如果找到乙個點使得刪掉這個點之後所有的聯通分支的點的個數都小於等於n 2個點,那麼就可以構造出一種方案使得每條邊被使用min sonsz u sonsz v 次。所以就是找樹的...

51 nod 蘋果曼和樹

1500 蘋果曼和樹 基準時間限制 1 秒 空間限制 131072 kb 分值 80 難度 5 級演算法題 收藏 關注 蘋果曼有一棵 n個點的樹。有一些 至少乙個 結點被標記為黑色,有一些結點被標記為白色。現在考慮乙個包含 k 0 k n 條樹邊的集合。如果蘋果曼刪除這些邊,那麼會將這個樹分成 k ...