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 ...