HDU 3586 Information Disturbing(二分+树形dp)

http://acm.split.hdu.edu.cn/showproblem.php?pid=3586

题意:

给定一个带权无向树,要切断所有叶子节点和1号节点(总根)的联系,每次切断边的费用不能超过上限limit,问在保证总费用<=m下的最小的limit。

思路:

对于上限limit我们可以二分查找。然后就是树形dp,看代码就可以理解的。

 #include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<sstream>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
typedef pair<int,ll> pll;
const int INF = 0x3f3f3f3f; //INF如果开的比较大的话那么cost要开long long,不然会超
const int maxn=+; int tot;
int n, m;
ll cost[maxn];
int head[*maxn]; struct node
{
int v,w,next;
}e[*maxn]; void addEdge(int u, int v, int w)
{
e[tot].v=v;
e[tot].w=w;
e[tot].next=head[u];
head[u]=tot++;
} void dfs(int u, int fa, int x)
{
cost[u]=;
bool flag=false;
for(int i=head[u];i!=-;i=e[i].next)
{
int v=e[i].v;
if(v==fa) continue;
flag=true;
dfs(v,u,x);
if(e[i].w>x) cost[u]+=cost[v];
else cost[u]+=min(cost[v],(ll)e[i].w);
}
if(!flag) cost[u]=INF;
} int main()
{
//freopen("in.txt","r",stdin);
while(~scanf("%d%d",&n,&m))
{
if(n== && m==) break;
tot=;
memset(head,-,sizeof(head));
int l=,r=;
for(int i=;i<n;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
addEdge(u,v,w);
addEdge(v,u,w);
r=max(r,w);
}
int ans=-;
while(l<=r)
{
int mid=(l+r)/;
dfs(,-,mid);
if(cost[]<=m) {ans=mid;r=mid-;}
else l=mid+;
}
printf("%d\n",ans);
}
return ;
}
上一篇:android中的位置服务(LBS)


下一篇:AngularJS中的表单验证