HDU 3586【树形DP+二分】

题意:

给出一棵树,和每条边的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
 1 #include <iostream>
2 #include <cstdio>
3 #include <string>
4 #include <cstring>
5 #include <algorithm>
6 #include <vector>
7 #include <map>
8
9 using namespace std;
10
11 const int MAX = 1000 + 10;
12 const int INF = 1001;
13 const int MAXM = 1000000 + 10;
14 struct TTree
15 {
16 int node, cost, next;
17 }Tree[MAX * 4];
18
19 int Pos[MAX];
20 int EdgeNumber;
21 int DP[MAX];
22 void init(int n)
23 {
24 EdgeNumber = n;
25 for(int i = 1; i <= n; ++i)
26 {
27 Pos[i] = i;
28 Tree[i].next = 0;
29 }
30 }
31 void addEdge(int from, int to, int cost)
32 {
33 ++EdgeNumber;
34 Tree[Pos[from]].next = EdgeNumber;
35 Tree[Pos[from] = EdgeNumber].node = to;
36 Tree[EdgeNumber].cost = cost;
37 Tree[EdgeNumber].next = 0;
38 }
39
40 void dfs(int father, int node, int upper)
41 {
42 int sum = 0;
43 for(int ix = Tree[node].next; ix != 0; ix = Tree[ix].next)
44 {
45 if(Tree[ix].node != father)
46 {
47 dfs(node, Tree[ix].node, upper);
48 if(Tree[ix].cost <= upper && Tree[ix].cost < DP[Tree[ix].node])
49 {
50 sum += Tree[ix].cost;
51 }
52 else
53 sum += DP[Tree[ix].node];
54 }
55 }
56 if(sum == 0)
57 sum = MAXM;
58 DP[node] = sum;
59 }
60
61 int solve(int maxSum)
62 {
63 int left = 1, right = INF;
64 int mid;
65 while(left < right)
66 {
67 mid = (left + right) >> 1;
68 dfs(-1, 1, mid);
69 if(DP[1] <= maxSum)
70 right = mid;
71 else
72 left = mid + 1;
73 }
74 return left;
75 }
76 int main()
77 {
78 freopen("in.txt","r",stdin);
79 int n, m;
80 int x, y, c;
81 while(scanf("%d%d", &n, &m) == 2 && (n || m))
82 {
83 init(n);
84 for(int i = 1; i <= n - 1; ++i)
85 {
86 scanf("%d%d%d", &x, &y, &c);
87 addEdge(x, y, c);
88 addEdge(y, x, c);
89 }
90 int ans = solve(m);
91 if(ans >= INF)
92 printf("-1\n");
93 else
94 printf("%d\n", ans);
95 }
96 return 0;
97 }



你可能感兴趣的:(HDU)