會議(樹形dp)

2022-09-01 08:57:09 字數 1541 閱讀 2602

題意:

有乙個村莊居住著n個村民,有n-1條路徑使得這n個村民的家聯通,每條路徑的長度都為1。現在村長希望在某個村民家中召開一場會議,村長希望所有村民到會議地點的距離之和最小,那麼村長應該要把會議地點設定在哪個村民的家中,並且這個距離總和最小是多少?若有多個節點都滿足條件,則選擇節點編號最小的那個點

輸入:第一行。乙個數n,表示有n個村民。

接下來n-1行,每行兩個數字a和b,表示村民a的家和村民b的家之間存在一條路徑。

輸出:一行輸出兩個數字x和y

x表示村長將會在哪個村民家中舉辦會議

y表示距離之和的最小值

輸入樣例:                                   輸出樣例:

4                              2 4

1 22 3

3 4【資料範圍】

70%資料n<=1000

100%資料n<=50000

思路:我們可以考慮樹形dp。首先以任意乙個點(在這裡我選了1)為根節點跑一遍dfs,求出

你選出的根節點到其它點的距離,即f[1]。

之後對於每乙個點i,fa表示i的父親。f[i]=f[fa]-(son[i]+1)+(n-(son[i]+1)),

son[i]表示i的子節點共有多少個;

簡單解釋,當根節點由fa轉移到i時,所有i的子節點以及i到根節點的距離都會減少1,而fa

除i以外的子節點以及fa到i的

距離都會增加1,即有上面的式子。而為了方便我們在預處理時直接讓son[i]+1,式子化簡得f[i]=f[fa]+n-2*son[i];

#includeusing

namespace

std;

const

int n=50010

;int n,head[n<<1],t,son[n],f[n],ans=0x3f3f3f3f,ans1=1

;struct

nodew[n

<<1

];inline

void add(int x,int

y)inline

intread()

while(ch>='

0'&&ch<='

9')

return x*f;

}inline

int dfs1(int u,int fa,int

num)

}inline

void dfs2(int u,int

fa)

else

if(f[v]==ans)

}dfs2(v,u);

}}int

main()

dfs1(

1,0,0

); ans=min(ans,f[1

]);//

for(int i=1;i<=n;i++) son[i]--;

dfs2(1,0

); printf(

"%d %d

",ans1,ans);

return0;

}

樹形DP 樹形DP四例

是時候練一下dp了!我的題單 portkey f u,if fu,i 表示以u uu為根節點的子樹中保留i ii條樹枝的最大蘋果數 f u,i max f max f fu,i max這些題是菜,但也不能輕視啊!include using namespace std define in read i...

HLOJ 樹形DP前置 DFS(樹形DP入門)

給定一棵 n nn 個點的樹,根為 t tt求每個點的父親是哪個點,t tt 的父親輸出 0 00第一行兩個整數 n,t n,tn,t接下來 n 1 n 1n 1 行,每行兩個整數 x,y x,yx,y,表示 x,y x,yx,y 之間有一條邊 n nn 行,第 i ii 行乙個整數,表示 i ii...

樹形dp小結

這些天做了一些樹形dp的題目,感覺有了些領悟,尤其是理解到樹形揹包就是分組揹包之後。選出幾道不錯的總結一下 hdu 1520 hdu 4003 poj 1155 poj 2486 hdu 4313 hdu 4340 hdu 1520 入門水題 每個節點有權值,子節點和父節點不能同時選,問最後能選的最...