P1272 重建道路
https://www.luogu.com.cn/problem/P1272
一个神奇的树形dp,大概就是下面这样转移的吧
dp[x][i]表示x为根,保留i个点最少删除几条边

#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn = 200+11;
const int INF = 1e7;
int dp[maxn][maxn];
vector<int>G[maxn];
void add(int x,int y){
G[x].push_back(y);
}
int siz[maxn];
int list[maxn];
int dfs(int x,int fa){
siz[x] =1;
dp[x][1] = 0;
for(int i=0;i<G[x].size();i++){
int p = G[x][i];
if(p == fa) continue;
dfs(p,x);
for(int i=1;i<=siz[x] + siz[p];i++) {
list[i] = dp[x][i];
if(i > 1) dp[x][i] = INF;
}
for(int i=1;i<=siz[x];i++){
for(int j=1;j<=siz[p];j++){
dp[x][i+j] = min(list[i] + dp[p][j],min(dp[x][i+j],list[i+j] + 1));
// 不删除当前边 删除当前边
}
}
//不删除当前边算贡
siz[x] += siz[p];
dp[x][1]++;
}
return 0;
}
int main(){
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
int n,p;
cin >> n >> p;
for(int i=1;i<=n+10;i++){
for(int j=2;j<=n+10;j++){
dp[i][j] = INF;
}
}
for(int i=1;i<n;i++){
int x,y;
cin>>x>>y;
add(x,y);
add(y,x);
}
dfs(1,-1);
int ans = dp[1][p];
for(int i=2;i<=n;i++){
ans = min(ans,dp[i][p]+1);
}
cout<<ans<<endl;
return 0;
}
寻找真正的热爱

浙公网安备 33010602011771号