luogu P1272 重建道路 樹形DP

2022-08-03 06:36:11 字數 1515 閱讀 6522

[luogu]p1272

重建道路

——!x^n+y^n=z^n

題目描述

一場可怕的**後,人們用n個牲口棚(1≤n≤150,編號1..n)重建了農夫john的牧場。由於人們沒有時間建設多餘的道路,所以現在從乙個牲口棚到另乙個牲口棚的道路是惟一的。因此,牧場運輸系統可以被構建成一棵樹。john想要知道另一次**會造成多嚴重的破壞。有些道路一旦被毀壞,就會使一棵含有p(1≤p≤n)個牲口棚的子樹和剩餘的牲口棚分離,john想知道這些道路的最小數目。

輸入輸出格式

輸入格式:

第1行:2個整數,n和p

第2..n行:每行2個整數i和j,表示節點i是節點j的父節點。

輸出格式:

單獨一行,包含一旦被破壞將分離出恰含p個節點的子樹的道路的最小數目。

輸入輸出樣例

輸入樣例1#:

11 6

1 21 3

1 41 5

2 62 7

2 84 9

4 10

4 11

輸出樣例1#:

說明【樣例解釋】

如果道路1-4和1-5被破壞,含有節點(1,2,3,6,7,8)的子樹將被分離出來

很容易想到樹形揹包,用f[i][j]表示以i為根,刪得只剩下j個點的最少刪除。

f[i][j]=min(v為i的孩子)[(v,i)應該留下,可兩個決策都減了,要-2]。

初始化:f[i][1]=邊數,f[root][1]=邊數-1。

一開始理解錯題意,以為root一定要保留,結果就gg了,呵呵。

**:

1

dp3 #include4 #include5 #include6

using

namespace

std;

7 inline int

read();

8int min(int x,int y)

9namespace

lyse[n*3

];15

intdp[n][n],pre[n],count[n],fa[n];

16int

n,p,cnt,ans;

17void add(int x,int y)

18void dfs(int

node)

28 ans=min(dp[node][p],ans);29}

30int

main()

42for(i=1;i<=n;i++) if(!fa[i])

43 printf("

%d\n

",ans);

44return0;

45}46}

47int

main()

51 inline int

read()

58while(c>='

0'&&c<='

9') kk=kk*10+c-'

0',c=getchar();

59return kk*ff;

60 }

luogu P1272 重建道路

一場可怕的 後,人們用n個牲口棚 1 n 150,編號1.n 重建了農夫john的牧場。由於人們沒有時間建設多餘的道路,所以現在從乙個牲口棚到另乙個牲口棚的道路是惟一的。因此,牧場運輸系統可以被構建成一棵樹。john想要知道另一次 會造成多嚴重的破壞。有些道路一旦被毀壞,就會使一棵含有p 1 p n...

luogu P1272 重建道路

很好的一道樹上dp 我會告訴你我想那個 2 想了乙個下午嗎?題面 一場可怕的 後,人們用n個牲口棚 1 n 150,編號1.n 重建了農夫john的牧場。由於人們沒有時間建設多餘的道路,所以現在從乙個牲口棚到另乙個牲口棚的道路是惟一的。因此,牧場運輸系統可以被構建成一棵樹。john想要知道另一次 會...

P1272 重建道路

p1272 重建道路 題意 有一棵n個點的樹,求刪掉最少的邊數,使得其中p個點的子樹和另一部分分離 dp i j 表示編號為i的點周圍組成j個點的樹最少要刪的邊數 初始狀態 dp i 1 連線這個點的邊數 每個點都是點數為1的樹 然後去考慮連線兩個點,使子樹的點數增多。有兩個點數都是1的樹dp i ...