【題意】:給出一棵樹,根節點為1,每條邊有一個代價。要求切去其所有的葉子節點,且總代價不能超過m,問切去的邊中的最大的邊最小是多少。
【題解】:最大值最小問題,基本上就是二分答案+判定。
這題的判定需要用到樹dp。
設狀態dp[u]為以u為根的子樹切去其下方葉子節點的最少代價。
非葉子節點:
dp[u] += min(dp[v], w(u, v)), v 為 u 兒子。
葉子節點:
dp[u] = inf;
最后判斷dp[1]與m的關系就可以了。
【代碼】:
【題解】:最大值最小問題,基本上就是二分答案+判定。
這題的判定需要用到樹dp。
設狀態dp[u]為以u為根的子樹切去其下方葉子節點的最少代價。
非葉子節點:
dp[u] += min(dp[v], w(u, v)), v 為 u 兒子。
葉子節點:
dp[u] = inf;
最后判斷dp[1]與m的關系就可以了。
【代碼】:
1 #include "iostream"
2 #include "cstdio"
3 #include "cstring"
4 #include "algorithm"
5 #include "vector"
6 #include "queue"
7 #include "cmath"
8 #include "string"
9 #include "cctype"
10 #include "map"
11 #include "iomanip"
12 using namespace std;
13 #define pb push_back
14 #define mp make_pair
15 #define fi first
16 #define se second
17 #define lc(x) (x << 1)
18 #define rc(x) (x << 1 | 1)
19 #define lowbit(x) (x & (-x))
20 #define ll long long
21 #define maxn 1010
22 const int inf = 1 << 20;
23 int n, m, limit;
24 int dp[maxn];
25 struct Edge {
26 int v, w;
27 Edge(){}
28 Edge(int _v, int _w) {
29 v = _v, w = _w;
30 }
31 };
32 vector<Edge> vec[maxn];
33
34 void dfs(int u, int fa) {
35 dp[u] = 0;
36 int size = vec[u].size();
37 for(int i = 0; i < size; i++) {
38 int v = vec[u][i].v, w = vec[u][i].w;
39 if(v == fa) continue;
40 if(w > limit) w = inf;
41 dfs(v, u);
42 dp[u] += min(dp[v], w);
43 }
44 if(!dp[u]) dp[u] = inf;
45 }
46
47 void solve() {
48 int ans = -1;
49 int l = 1, r = 1000;
50 while(l <= r) {
51 int mid = (l + r) >> 1;
52 limit = mid;
53 dfs(1, -1);
54 if(dp[1] <= m) ans = mid, r = mid - 1;
55 else l = mid + 1;
56 }
57 cout << ans << endl;
58 }
59
60 int main() {
61 while(~scanf("%d%d", &n, &m)) {
62 if(!n) break;
63 for(int i = 1; i <= n; i++) vec[i].clear();
64 for(int i = 1; i < n; i++) {
65 int u, v, w;
66 scanf("%d%d%d", &u, &v, &w);
67 vec[u].pb(Edge(v, w));
68 vec[v].pb(Edge(u, w));
69 }
70 solve();
71 }
72 return 0;
73 }
74
2 #include "cstdio"
3 #include "cstring"
4 #include "algorithm"
5 #include "vector"
6 #include "queue"
7 #include "cmath"
8 #include "string"
9 #include "cctype"
10 #include "map"
11 #include "iomanip"
12 using namespace std;
13 #define pb push_back
14 #define mp make_pair
15 #define fi first
16 #define se second
17 #define lc(x) (x << 1)
18 #define rc(x) (x << 1 | 1)
19 #define lowbit(x) (x & (-x))
20 #define ll long long
21 #define maxn 1010
22 const int inf = 1 << 20;
23 int n, m, limit;
24 int dp[maxn];
25 struct Edge {
26 int v, w;
27 Edge(){}
28 Edge(int _v, int _w) {
29 v = _v, w = _w;
30 }
31 };
32 vector<Edge> vec[maxn];
33
34 void dfs(int u, int fa) {
35 dp[u] = 0;
36 int size = vec[u].size();
37 for(int i = 0; i < size; i++) {
38 int v = vec[u][i].v, w = vec[u][i].w;
39 if(v == fa) continue;
40 if(w > limit) w = inf;
41 dfs(v, u);
42 dp[u] += min(dp[v], w);
43 }
44 if(!dp[u]) dp[u] = inf;
45 }
46
47 void solve() {
48 int ans = -1;
49 int l = 1, r = 1000;
50 while(l <= r) {
51 int mid = (l + r) >> 1;
52 limit = mid;
53 dfs(1, -1);
54 if(dp[1] <= m) ans = mid, r = mid - 1;
55 else l = mid + 1;
56 }
57 cout << ans << endl;
58 }
59
60 int main() {
61 while(~scanf("%d%d", &n, &m)) {
62 if(!n) break;
63 for(int i = 1; i <= n; i++) vec[i].clear();
64 for(int i = 1; i < n; i++) {
65 int u, v, w;
66 scanf("%d%d%d", &u, &v, &w);
67 vec[u].pb(Edge(v, w));
68 vec[v].pb(Edge(u, w));
69 }
70 solve();
71 }
72 return 0;
73 }
74
發表于 2012-04-05 14:10 y @ The Angry Teletubbies 閱讀(196) 評論(0) 編輯 收藏 引用 所屬分類: DP 、Dichotomy & Trichotomy