HDU 3586 Information Disturbing 树状DP+二分

来源:互联网 发布:2017大数据的特征包含 编辑:程序博客网 时间:2024/05/23 18:45

题意:给出一棵树,和每条边的cost值,设置一个界限,要求切断所有叶子结点,切断的边的cost不能超过界限值,并且切断的边的总和不能超过m,求出这个最小界限值。

思路:二分枚举最小界限值,用树状DP求出在这个限制下的最小花费是否小于m。

#include <cstdio>#include <cstring>#include <string>#include <iostream>#include <queue>#include <algorithm>#include <map>#include <vector>#include <cmath>#include <stack>using namespace std;#define ll long long#define int64 __int64#define M 100005#define N 1005#define inf 1000010#define mod 1000000007struct node{int ev , cost;};int n , m , MAX , dp[N];vector<node> son[N];void Dfs(int s , int fa , int k){int i , up = son[s].size() , fg = 0;dp[s] = 0;for (i = 0 ; i < up ; i++){int v = son[s][i].ev;int cost = son[s][i].cost;if (v == fa)continue;fg = 1;Dfs(v,s,k);if (cost <= k)dp[s] += min(dp[v],cost);else dp[s] += dp[v];}if(!fg)dp[s] = inf;}int Solve(){int l = 0 , r = MAX , mid , ret = -1;while (l <= r){mid = (l+r)>>1;Dfs(1,0,mid);if (dp[1] <= m){ret = mid;r = mid-1;}elsel = mid+1;}return ret;}int main(){while (scanf("%d%d",&n,&m) , m+n){int i;MAX = 0;for (i = 1 ; i < n ; i++){int s , e , w;scanf("%d%d%d",&s,&e,&w);node temp;temp.ev = e;temp.cost = w;son[s].push_back(temp);temp.ev = s;son[e].push_back(temp);MAX = max(MAX,w);}printf("%d\n",Solve());for (i = 1 ; i <= n ; i++)son[i].clear();}return 0;}


 

原创粉丝点击