洛谷 P1272 重建道路
2016-11-12 23:34
246 查看
题目描述
一场可怕的地震后,人们用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 2 1 3 1 4 1 5 2 6 2 7 2 8 4 9 4 10 4 11
输出样例#1:
2
说明
【样例解释】如果道路1-4和1-5被破坏,含有节点(1,2,3,6,7,8)的子树将被分离出来
设f[i][j]表示i为根节点,剩下j个节点的最小操作次数。
#include<algorithm> #include<iostream> #include<cstdio> using namespace std; const int N=155; int n,p,cnt,ans=1e9+7,hd ,f ,du ;//节点i分离出j个节点的子树的最小次数 struct edge { int to,nxt; }v ; void addedge(int x,int y) { ++cnt; v[cnt].to=y; v[cnt].nxt=hd[x]; hd[x]=cnt; } void dfs(int u) { f[u][1]=du[u]; for(int i=hd[u];i;i=v[i].nxt) { dfs(v[i].to); for(int j=p;j>=2;j--) for(int k=1;k<j;k++) f[u][j]=min(f[u][j],f[u][j-k]+f[v[i].to][k]-2); } } int main() { scanf("%d%d",&n,&p); for(int i=1;i<=n-1;i++) { int x,y; scanf("%d%d",&x,&y); addedge(x,y); ++du[x],++du[y]; } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) f[i][j]=200; dfs(1); for(int i=1;i<=n;i++) ans=min(ans,f[i][p]); printf("%d\n",ans); return 0; }
相关文章推荐
- 洛谷 p1272 重建道路 树形dp
- 洛谷 P1272 重建道路
- 洛谷 P1272 重建道路
- 洛谷 P1272 重建道路
- 洛谷P3905 道路重建
- P1272 重建道路
- luogu P1272 重建道路
- 【洛谷1272】重建道路(树形DP)
- P1272 重建道路(树形dp)
- P1272 重建道路
- 1089: 道路重建(dij 最短路径)
- 洛谷1462 通往奥格瑞玛的道路
- 洛谷 通往奥格瑞玛的道路
- LG P3905 道路重建
- 洛谷 P2296 寻找道路【bfs+spfa】
- 最短路【洛谷P1462】 通往奥格瑞玛的道路
- 洛谷 1119 灾后重建 Floyd
- 洛谷 P1119 灾后重建
- 【NOIP2009】洛谷1070 道路游戏
- AC日记——寻找道路 洛谷 P2296