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 node
24 {
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 }

 

posted @ 2017-08-11 16:20  Kayden_Cheung  阅读(175)  评论(0编辑  收藏  举报
//目录