bzoj4813 樹形dp 小Q的棋盤

2021-08-08 08:16:47 字數 1450 閱讀 7783

description

小q正在設計一種棋類遊戲。在小q設計的遊戲中,棋子可以放在棋盤上的格點中。某些格點之間有連線,棋子只能

在有連線的格點之間移動。整個棋盤上共有v個格點,編號為0,1,2…,v-1,它們是連通的,也就是說棋子從任意格

點出發,總能到達所有的格點。小q在設計棋盤時,還保證棋子從乙個格點移動到另外任一格點的路徑是唯一的。

小q現在想知道,當棋子從格點0出發,移動n步最多能經過多少格點。格點可以重複經過多次,但不重複計數。

input

第一行包含2個正整數v,n,其中v表示格點總數,n表示移動步數。

接下來v-1行,每行兩個數ai,bi,表示編號為ai,bi的兩個格點之間有連線。

v,n≤ 100, 0 ≤ai,bioutput

輸出一行乙個整數,表示最多經過的格點數量。

sample input

5 2

1 02 1

3 24 3

sample output

3
題解

我覺得我好辣雞。。想到是樹形dp結果不會轉移。。最後發現轉移賊簡單

設g[x][i]表示從x走i步不回來

f[x][i]表示從x走i步最後回到x點

轉移如下

g[x][i]=max(g[x][i],g[y][j-1]+f[x][i-j]);

不回來的話,就要留一步從子樹回來的,還有從其他子樹過來的

f[x][i]=max(f[x][i],f[y][j-2]+f[x][i-j]);

回來,那麼我走下去還要走回來,這棵子樹和其他子樹一起回到我

g[x][i]=max(g[x][i],f[y][j-2]+g[x][i-j]);

不回來 上面算了在現在的子樹不回來 那麼現在算其他子樹不回來

#include

#include

#include

#include

#include

using

namespace

std;

struct node

a[210];int len,last[110];

void ins(int x,int y)

int g[110][110],f[110][110];

//g[x][i]從x往下走i步,不回來

//f[x][i]從x往下走i步,回來

int n,m;

void treedp(int x,int fa)}}

}}int main()

treedp(1,0);

printf("%d\n",g[1][m]);

return

0;}

BZOJ4813 Cqoi2017 小Q的棋盤

找以起點為起點的乙個最長鏈,最優一定是在最長鏈上不走回頭路的,所以相當於最長鏈上的邊代價是1,非最長鏈的邊代價是2 因為要走回去 每付出一次代價就可以使訪問到的點數 1,那麼貪心即可 include include include include include include include in...

bzoj4813 Cqoi2017 小Q的棋盤

小q正在設計一種棋類遊戲。在小q設計的遊戲中,棋子可以放在棋盤上的格點中。某些格點之間有連線,棋子只能在有連線的格點之間移動。整個棋盤上共有v個格點,編號為0,1,2 v 1,它們是連通的,也就是說棋子從任意格點出發,總能到達所有的格點。小q在設計棋盤時,還保證棋子從乙個格點移動到另外任一格點的路徑...

BZOJ4813 Cqoi2017 小Q的棋盤

給出一棵樹,從根節點出發,走n步,求最多能經過多少個點 重複經過不算 貪心本來想著樹形dp,太麻煩了,懶得碼 首先我們把最長鏈留到最後走,這樣子我們就可以一次性將最長鏈走完了,那麼最長鏈的每條邊的代價就是1 而其它邊的代價就為2 因為要往回走 然後貪心就好了 特殊情況 1.最長鏈的長度 步數,直接輸...