首页 > 代码库 > HDU 3586 Information Disturbing(二分+树形dp)
HDU 3586 Information Disturbing(二分+树形dp)
http://acm.split.hdu.edu.cn/showproblem.php?pid=3586
题意:
给定一个带权无向树,要切断所有叶子节点和1号节点(总根)的联系,每次切断边的费用不能超过上限limit,问在保证总费用<=m下的最小的limit。
思路:
对于上限limit我们可以二分查找。然后就是树形dp,看代码就可以理解的。
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<sstream> 6 #include<vector> 7 #include<stack> 8 #include<queue> 9 #include<cmath>10 #include<map>11 #include<set>12 using namespace std;13 typedef long long ll;14 typedef pair<int,ll> pll;15 const int INF = 0x3f3f3f3f; //INF如果开的比较大的话那么cost要开long long,不然会超16 const int maxn=1000+5;17 18 int tot;19 int n, m;20 ll cost[maxn];21 int head[2*maxn];22 23 struct node24 {25 int v,w,next;26 }e[2*maxn];27 28 void addEdge(int u, int v, int w)29 {30 e[tot].v=v;31 e[tot].w=w;32 e[tot].next=head[u];33 head[u]=tot++;34 }35 36 void dfs(int u, int fa, int x)37 {38 cost[u]=0;39 bool flag=false;40 for(int i=head[u];i!=-1;i=e[i].next)41 {42 int v=e[i].v;43 if(v==fa) continue;44 flag=true;45 dfs(v,u,x);46 if(e[i].w>x) cost[u]+=cost[v];47 else cost[u]+=min(cost[v],(ll)e[i].w);48 }49 if(!flag) cost[u]=INF;50 }51 52 int main()53 {54 //freopen("in.txt","r",stdin);55 while(~scanf("%d%d",&n,&m))56 {57 if(n==0 && m==0) break;58 tot=0;59 memset(head,-1,sizeof(head));60 int l=0,r=0;61 for(int i=1;i<n;i++)62 {63 int u,v,w;64 scanf("%d%d%d",&u,&v,&w);65 addEdge(u,v,w);66 addEdge(v,u,w);67 r=max(r,w);68 }69 int ans=-1;70 while(l<=r)71 {72 int mid=(l+r)/2;73 dfs(1,-1,mid);74 if(cost[1]<=m) {ans=mid;r=mid-1;}75 else l=mid+1;76 }77 printf("%d\n",ans);78 }79 return 0;80 }
HDU 3586 Information Disturbing(二分+树形dp)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。