P1272 重建道路

2021-09-11 04:09:28 字數 1058 閱讀 3217

p1272 重建道路

題意:有一棵n個點的樹,求刪掉最少的邊數,使得其中p個點的子樹和另一部分分離

dp[i][j]表示編號為i的點周圍組成j個點的樹最少要刪的邊數

初始狀態:dp[i][1]=連線這個點的邊數(每個點都是點數為1的樹)

然後去考慮連線兩個點,使子樹的點數增多。

有兩個點數都是1的樹dp[i][1]=a,dp[j][1]=b,這兩個點合併後要刪的邊是a+b-2,-2是因為新增的這條邊在a中和b中分別包含了一次。

推廣一下,兩棵不相連的樹,點數任意,合併之後要刪的邊也是a+b-2

可以利用dfs回溯來完成連邊,對於乙個結點,先處理子結點的和子節點下面的點構成不同大小的樹的狀態,然後回來更新當前結點的狀態。

轉移方程:dp[u][i]=min(dp[u][i],dp[u][j]+dp[v][i-j]-2)

#include

using namespace std;

int n,p;

int dp[

155]

[155];

vector<

int>e[

155]

;void

dfs(

int x,

int fa)}}

}int

main()

memset

(dp,

0x3f

,sizeof

(dp));

for(

int i=

1;i<=n;i++

) dp[i][1

]=e[i]

.size()

;dfs(1

,-1)

;int ans=

999999999

;for

(int i=

1;i<=n;i++

)ans=

min(ans,dp[i]

[p])

;printf

("%d\n"

,ans)

;return0;

}

P1272 重建道路

lin klink link 這道題出的其實挺好的 顯然是乙個樹形dpdp dp問題最開始想複雜了 後來發現很簡單 一直以為是n 3做法 我們用dpu k dp dp u,k 表示在以u uu為根的子樹中,剔除k kk個的最小需要切的邊數 那麼初值就是dpu 1 d uu dp du u dpu,1...

P1272 重建道路

一開始狀態定義錯了 所以沒有對qwq,以及有幾個坑qwq 首先 f i j 表示以 i 為根的子樹,切除 j 個節點所需要切除的最小邊數,而我一開始定義的是表示以 i 為根的子樹,切除後生成一顆有 j 個節點的子樹,所需要切除的最小邊數。為什麼我的不行吶?因為對於乙個新的子節點更新狀態,它能生成多大...

洛谷 P1272 重建道路

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