重建道路
来源:互联网 发布:pop3端口号 编辑:程序博客网 时间:2024/04/29 18:52
问题 M(1288): 【基础算法】重建道路
时间限制: 1 Sec 内存限制: 64 MB提交: 93 解决: 42
[提交][状态][我的提交]
题目描述
一场可怕的地震后,人们用N个牲口棚(1≤N≤150,编号1..N)重建了Farmer John的牧场。由于人们没有时间建设多余的道路,所以现在从一个牲口棚到另一个牲口棚的道路是惟一的。因此,牧场运输系统可以被构建成一棵树。
John想要知道另一次地震会造成多严重的破坏。有些道路一旦被毁坏,就会使一棵含有P(1≤P≤N)个牲口棚的子树和剩余的牲口棚分离,John想知道这些道路的最小数目。
例如,如图所示的牧场,要求P=6。如果道路1-4和1-5被破坏,含有节点(1,2,3,6,7,8)的子树将被分离出来。
输入
第1行:2个整数,N和P
第2..N行:每行2个整数I和J,表示节点I是节点J的父节点。
输出
第1行:1个整数,表示一旦被破坏将分离出恰含P个节点的子树的道路的最小数目。
样例输入
(如果复制到控制台无换行,可以先粘贴到文本编辑器,再复制)
11 61 21 31 41 52 62 72 84 94 104 11
样例输出
2
分析:多叉树转二叉树,分配,刚开始做题时没有看见是分出一棵子树,还以为分出p个点就可以了,然后WA了很久(TAT),后来发现了,又懒得改了吧p和n-p都做一次dfs,再特判是否为树。
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<stack>#include<algorithm>#include<vector>using namespace std;const int N=150+10;const int inf=0x7f7f7f7f;void getint(int&num){ char c;int flag=1;num=0; while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1; while(c>='0'&&c<='9'){num=num*10+c-48;c=getchar();} num*=flag;}struct bian{ int v,next;}arr[N<<1];struct node{ int l,r;}tree[N<<1];int n,p,a,b,cnt,root,Ans;int fir[N],way[N],son[N],dp[N][N];bool fa[N],vis[N][N];void link(int a,int b){ arr[++cnt].v=a,arr[cnt].next=fir[b],fir[b]=cnt;}void Son(int x){ if(!x) return ; Son(tree[x].l),Son(tree[x].r); son[x]=son[tree[x].l]+son[tree[x].r]+1;}void dfs(int x,int k){ if(vis[x][k]) return ; vis[x][k]=1; int tmp=inf; if(!k){dp[x][k]=0;return ;}if(k==son[tree[x].l]+1)tmp=min(tmp,1); if(!tree[x].l&&!tree[x].r); else if(!tree[x].l){ if(son[tree[x].r]>=k){ dfs(tree[x].r,k); tmp=min(tmp,dp[tree[x].r][k]); } if(son[tree[x].r]>=k-1){ dfs(tree[x].r,k-1); tmp=min(tmp,dp[tree[x].r][k-1]+way[x]); } } else if(!tree[x].r){ if(son[tree[x].l]>=k){ dfs(tree[x].l,k); tmp=min(tmp,dp[tree[x].l][k]); }} else{if(son[tree[x].r]>=k-son[tree[x].l]-1&&k-son[tree[x].l]-1>=0){dfs(tree[x].r,k-son[tree[x].l]-1);tmp=min(tmp,dp[tree[x].r][k-son[tree[x].l]-1]+1);} for(int i=0;i<=k;i++){ if(son[tree[x].l]<i||son[tree[x].r]<k-i) continue ; dfs(tree[x].l,i); dfs(tree[x].r,k-i); tmp=min(tmp,dp[tree[x].l][i]+dp[tree[x].r][k-i]); } } dp[x][k]=tmp;}int main(){ getint(n),getint(p);if(p==n){printf("0\n");return 0;}if(p==1){printf("1\n");return 0;} for(int i=1;i<n;i++){ getint(a),getint(b); link(b,a),fa[b]=1; way[a]++,way[b]++; } for(int i=1;i<=n;i++)if(!fa[i]){ root=i;break ; } for(int i=1;i<=n;i++){ tree[i].l=arr[fir[i]].v; int now=tree[i].l; for(int j=arr[fir[i]].next;j;j=arr[j].next) tree[now].r=arr[j].v,now=arr[j].v; } Son(root),dfs(root,n-p),dfs(root,p);if(dp[root][p]<2||dp[root][n-p]<2)printf("%d\n",min(dp[root][n-p],dp[root][p]));elseprintf("%d\n",dp[root][n-p]);}
0 0
- 道路重建
- 重建道路
- 道路重建
- 洛谷 P1272 重建道路
- 洛谷 P1272 重建道路
- 洛谷 P1272 重建道路
- 洛谷 P1272 重建道路
- 洛谷 P1272 重建道路
- 【图论】[luoguP3905]道路重建
- 洛谷P3905 道路重建
- 重建道路(树上背包)
- Luogu P3905 道路重建
- 一、树形dp(3)重建道路
- 树形DP 洛谷P1272 道路重建
- 【洛谷1272】重建道路(树形DP)
- [luogu1272]重建道路(树形dp)
- 【Luogu1272】重建道路(动态规划)
- 洛谷 p1272 重建道路 树形dp
- Java内部类
- Long型时间轴时间类型转为正常格式时间
- Ubuntu16.04 安装 Visual Studio Code之后启动不起来
- 不正经运维狗的文档6
- Android事件分发机制
- 重建道路
- 《JavaScript高级程序设计 第三版》学习笔记 (三)引用类型详解
- SASS
- js中获取浏览器信息
- [Powershell]导出域内主机信息
- Java实现Zip文件的解压和压缩_ZipUtil
- k-Nearest Neighbor-最近邻分类算法
- 微信6.5.7手机号码如何解绑
- springboot jsp mybatis 实例