HDU 3586【树形DP+二分】
2011-09-22 18:59
381 查看
题目:Information Disturbing
题意:
给出一棵树,和每条边的cost值,设置一个界限,要求切断所有叶子结点,切断的边的cost不能超过界限值,并且切断的边的总和不能超过m,求出这个最小界限值。
解题思路:
很明显的一道树型DP,DP[v],表示切断根结点的v的子树的最小花费,那么这个界限怎么处理呢,由于界限值范围要比总和m小得多,才1-1000,可以用二分枚举,这样在选择切边时可以根据这个枚举值进行判断处理。每个结点v,设其儿子结点为x1,x2,x3...则DP[v] = Min{DP[x1],Node[x1].cost} + Min{DP[x2], Node[x2].cost} + ...,当然,要判断Node[x].cost是否小于枚举的界限,Node[x].cost表示边(v,x)的cost值。
View Code
题意:
给出一棵树,和每条边的cost值,设置一个界限,要求切断所有叶子结点,切断的边的cost不能超过界限值,并且切断的边的总和不能超过m,求出这个最小界限值。
解题思路:
很明显的一道树型DP,DP[v],表示切断根结点的v的子树的最小花费,那么这个界限怎么处理呢,由于界限值范围要比总和m小得多,才1-1000,可以用二分枚举,这样在选择切边时可以根据这个枚举值进行判断处理。每个结点v,设其儿子结点为x1,x2,x3...则DP[v] = Min{DP[x1],Node[x1].cost} + Min{DP[x2], Node[x2].cost} + ...,当然,要判断Node[x].cost是否小于枚举的界限,Node[x].cost表示边(v,x)的cost值。
View Code
#include <iostream> #include <cstdio> #include <string> #include <cstring> #include <algorithm> #include <vector> #include <map> using namespace std; const int MAX = 1000 + 10; const int INF = 1001; const int MAXM = 1000000 + 10; struct TTree { int node, cost, next; }Tree[MAX * 4]; int Pos[MAX]; int EdgeNumber; int DP[MAX]; void init(int n) { EdgeNumber = n; for(int i = 1; i <= n; ++i) { Pos[i] = i; Tree[i].next = 0; } } void addEdge(int from, int to, int cost) { ++EdgeNumber; Tree[Pos[from]].next = EdgeNumber; Tree[Pos[from] = EdgeNumber].node = to; Tree[EdgeNumber].cost = cost; Tree[EdgeNumber].next = 0; } void dfs(int father, int node, int upper) { int sum = 0; for(int ix = Tree[node].next; ix != 0; ix = Tree[ix].next) { if(Tree[ix].node != father) { dfs(node, Tree[ix].node, upper); if(Tree[ix].cost <= upper && Tree[ix].cost < DP[Tree[ix].node]) { sum += Tree[ix].cost; } else sum += DP[Tree[ix].node]; } } if(sum == 0) sum = MAXM; DP[node] = sum; } int solve(int maxSum) { int left = 1, right = INF; int mid; while(left < right) { mid = (left + right) >> 1; dfs(-1, 1, mid); if(DP[1] <= maxSum) right = mid; else left = mid + 1; } return left; } int main() { freopen("in.txt","r",stdin); int n, m; int x, y, c; while(scanf("%d%d", &n, &m) == 2 && (n || m)) { init(n); for(int i = 1; i <= n - 1; ++i) { scanf("%d%d%d", &x, &y, &c); addEdge(x, y, c); addEdge(y, x, c); } int ans = solve(m); if(ans >= INF) printf("-1\n"); else printf("%d\n", ans); } return 0; }
相关文章推荐
- HDU 3586 Information Disturbing (树形DP+二分)
- HDU-3586 Information Disturbing 树形dp+二分
- hdu 3586 Information Disturbing 树形dp+二分
- HDU - 3586 Information Disturbing【树形dp+二分】
- HDU 3586 Information Disturbing(二分+树形dp)
- hdu 3586 Information Disturbing (树形dp+二分)
- HDU 3586 Information Disturbing 二分+树形DP
- hdu 3586 Information Disturbing(树形dp + 二分)
- HDU 3586 Information Disturbing (树形DP+二分)
- hdu 3586 Information Disturbing (树形dp+二分)
- HDU 3586 Information Disturbing 树形DP+二分
- HDU 3586 Information Disturbing(树形DP + 二分)
- HDU 3586 Information Disturbing (树形dp+二分)
- HDU 3586 - Information Disturbing(二分+树形DP)
- hdu 3586 树形dp +二分
- hdu 3586(树形dp+二分)
- HDU 3586 Information Disturbing (二分+树形dp)
- hdu 3586 (树形dp+二分)
- 【HDU】3586 Information Disturbing 二分+树形dp
- hdu 3586 树形dp+二分