【洛谷P1272】 重建道路
重建道路
一场可怕的地震后,人们用N个牲口棚(1≤N≤150,编号1..N)重建了农夫John的牧场。由于人们没有时间建设多余的道路,所以现在从一个牲口棚到另一个牲口棚的道路是惟一的。因此,牧场运输系统可以被构建成一棵树。John想要知道另一次地震会造成多严重的破坏。有些道路一旦被毁坏,就会使一棵含有P(1≤P≤N)个牲口棚的子树和剩余的牲口棚分离,John想知道这些道路的最小数目。
显然是一道树形DP
然后看题解
树上分组背包问题
dp[u][i][j]表示以u为根的子树中,前i个子树中留下j个的最小花费
首先,dp[u][size[u]][1]=son_num[u]
以u为节点的子树留下1个节点的花费为u的子树个数
dp[u][i][j]=min(dp[u][i][j],dp[u][i-1][j-k]+dp[v][size[v]][k]-1);
i这一维可以滚动数组滚掉
#include<iostream> #include<cstring> #include<cstdio> #define N 155 int n,p,dp[N][N],out[N],in[N]; struct NODE{ int to,next; } e[N]; int Head[N],num; inline void add(int x,int y){ e[++num].to=y; e[num].next=Head[x]; Head[x]=num; } inline int read(){ int x=0; char c=getchar(); while(c<'0'||c>'9') c=getchar(); while('0'<=c&&c<='9') { x=(x<<3)+(x<<1)+c-'0'; c=getchar(); } return x; } inline int min(int a,int b){ return a<b?a:b; } int dfs(int u){ dp[u][1]=out[u]; int sum=1; for(int i=Head[u];i;i=e[i].next){ int v=e[i].to; int sz=dfs(v); sum+=sz; for(int j=sum;j>=0;j--) for(int k=0;k<=min(sz,j);k++){ dp[u][j]=min(dp[u][j],dp[u][j-k]+dp[v][k]-1); } } dp[u][sum]=0; return sum; } int main() { memset(dp,0x3f,sizeof(dp)); scanf("%d%d",&n,&p); int x,y; for(int i=1;i<n;i++){ x=read(); y=read(); add(x,y); out[x]++; in[y]++; } int st; for(int i=1;i<=n;i++) if(!in[i]) { st=i; break; } dfs(st); int ans=0x7fffffff; for(int i=1;i<=n;i++) ans=min(ans,dp[i][p]+(i==st?0:1)); printf("%d\n",ans); return 0; }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用
· 程序员常用高效实用工具推荐,办公效率提升利器!
· Janus Pro:DeepSeek 开源革新,多模态 AI 的未来
· 【译】WinForms:分析一下(我用 Visual Basic 写的)