51nod 1322 關於樹的函式

2022-05-19 19:38:19 字數 1298 閱讀 6809

給出n個點的兩棵無根樹,編號都是從0到n-1

現在每棵樹任意選出一條邊割斷,設第一棵樹選出的邊為e1,第二棵樹選出的邊為e2

很顯然割斷後兩棵樹各分成了四棵樹,設第一棵樹分成了a1樹和b1樹,第二棵樹分成了a2樹和b2樹

設s(a,b)為a樹和b樹之間相同編號的點的個數

那麼割斷這兩條邊的價值為s(a1,b1),s(a1,b2),s(a2,b1),s(a2,b2)中的最大值的平方

求出每對e1,e2的價值和

又是一道卡了挺久的題

我們把節點全部+1,

把第二棵樹的節點編號設為n+1到2n(方便操作)

設兩棵樹的根節點分別為1和n+1

先在第一棵樹中找到乙個非根節點,然後在第二棵樹中找到另乙個非根節點

對於這兩個節點顯然有三種情況:

1.取兩個節點的子樹

2.取其中乙個點的子樹,另乙個點的反子樹(就是除了子樹外的點)

3.取兩個節點的反子樹

然後對於三種情況更新答案就行了

具體操作有點麻煩,看**吧(有點小懶)

ps:不知道該分到哪個專題,看了一下路牌,發現dalao都說是樹形計數dp,那我就只好分成樹形計數dp

#include#include

#include

#include

#include

using

namespace

std;

typedef

long

long

ll;struct

node

a[21000];int len,last[8100

];void ins(int x,int

y)int tot[8100

],n;

bool v[4100][4100

];void pre(int x,int

fa)}

ll ans;

ints;

int dou(int x)

void getd(int x,int fa,intp)}

void solve(int x,int

fa)}

intmain()

for(int i=1;i)

memset(v,

false,sizeof

(v));

pre(

1,0);pre(n+1,0

); ans=0;solve(1,0

); printf(

"%lld\n

",ans);

return0;

}

51Nod 1322 關於樹的函式

acm模版 典型的樹歸問題,複雜度 o n2 暫且不說樹歸部分,我們先考慮任何一種狀態下如何求 s e1,e 2 2 其實這裡我們並不需要直接算出 a1 a2 b1 b2,只需要根據部分資料就能推出其他資料。假如 a1 集合中有 n 個結點,那麼 a2 集合中有 n n 個結點。假如 b1 集合中有...

51nod 1737 樹的重心

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

51nod 1405 樹的距離之和

給定一棵無根樹,假設它有n個節點,節點編號從1到n,求任意兩點之間的距離 最短路徑 之和。input 第一行包含乙個正整數n n 100000 表示節點個數。後面 n 1 行,每行兩個整數表示樹的邊。output 每行乙個整數,第i i 1,2,n 行表示所有節點到第i個點的距離之和。input示例...