hdu3586(树形dp+二分)
2016-04-07 21:07
190 查看
链接:点击打开链接
题意:根节点为1的一棵树,删除一些边使叶子节点都不能到达根节点,并且边权和不能大于M,使删除边的最大值最小,并输出
代码:
题意:根节点为1的一棵树,删除一些边使叶子节点都不能到达根节点,并且边权和不能大于M,使删除边的最大值最小,并输出
代码:
#include <queue> #include <vector> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <iostream> using namespace std; const int INF=1100000; struct node{ int to,cost; }; int n,m,dp[1005],used[1005]; vector<node> G[1005]; void dfs(int s,int cnt){ int i,j,tmp; used[s]=1; for(i=0;i<G[s].size();i++){ tmp=G[s][i].to; if(!used[tmp]){ dfs(tmp,cnt); if(G[s][i].cost>cnt) //大于限制直接取子节点的值 dp[s]+=dp[tmp]; else dp[s]+=min(dp[tmp],G[s][i].cost); } } } int judge(int mid){ int i; for(i=1;i<=n;i++){ //叶子节点为INF,INF不要过大否则加的时候后 if(G[i].size()==1&&i!=1) //超上限 dp[i]=INF; else dp[i]=0; } memset(used,0,sizeof(used)); dfs(1,mid); if(dp[1]<=m) return 1; return 0; } int main(){ int i,j,l,r,u,v,w,ans,mid; while(scanf("%d%d",&n,&m)!=EOF&&(n||m)){ r=0; for(i=0;i<=n;i++) G[i].clear(); for(i=0;i<n-1;i++){ scanf("%d%d%d",&u,&v,&w); G[u].push_back((node){v,w}); G[v].push_back((node){u,w}); r=max(r,w); //二分上限 } l=1,ans=-1; //最大值最小因此进行二分 while(l<=r){ mid=(l+r)>>1; if(judge(mid)){ ans=mid; r=mid-1; } else l=mid+1; } printf("%d\n",ans); } return 0; }
相关文章推荐
- 作业5
- 关于C语言的问卷调查
- HDU 1114 完全背包 HDU 2191 多重背包
- Dialog源码分析
- 本周学习的相关知识
- java编写了24小时制的时间加减
- POJ-2513 Colored Sticks
- Java类集笔记
- 2016年3月30日作业
- 关于one-hot编码引发相关问题的一点感想
- R使用总结
- ListOperations
- 四则运算网页版
- Only Link: Reading links for button/a etc
- 提高设计团队效率的7种方法
- ZCTF-final-restaurant1
- 编译libjpeg
- #leetcode#237. Delete Node in a Linked List
- WKWebView的简单介绍
- 第三章-指针