首页 > 代码库 > 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)