HDU 3586 Information Disturbing【二分 + 樹形DP】
阿新 • • 發佈:2021-02-17
技術標籤:# 動態規劃——樹形DP
Information Disturbing |
---|
題意: 一棵有邊權的樹,要求刪除一些邊,使得根節點1和所有的葉子節點斷開聯絡。要求是:
- 刪除的邊的權值和必須小於m
- 刪除的邊權的最大值儘可能小
題解: 兩個條件看似是不能統一的,總和必須小於m,但是最大權值又要儘可能小。
舉個栗子,如果DFS過程中追求權值和最小,那麼將會得到答案6,但這個卻不是最小的最大權。
對於這種,就應該去列舉最大權,然後DFS驗證是否正確。當然,應該二分列舉。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1100;
int n, m;
int dp[maxn];
int cnt, head[maxn];
struct edge { int v, w, next; } e[maxn << 1];
void add (int u, int v, int w) {
e[++cnt] = {v, w, head[u]}; head[u] = cnt;
e[++cnt] = {u, w, head[v]}; head[v] = cnt;
}
int DFS (int u, int fa, int lim) {
dp[u] = 0;
for (int i = head[u]; i; i = e[i].next) {
int v = e[i].v, w = e[i].w;
if (v == fa) continue;
int c = (w > lim ? m + 1 : w);
dp[u] += min(DFS(v, u, lim), c);
}
return dp[u] ? dp[u] : m + 1;
}
void run () {
cnt = 0;
memset(head, 0, sizeof head);
for (int i = 1, u, v, w; i < n; ++i) {
scanf("%d%d%d", & u, &v, &w);
add(u, v, w);
}
int ans = -1;
int l = 0, r = m;
while (l <= r) {
int mid = (l + r) >> 1;
if (DFS(1, 0, mid) <= m) ans = mid, r = mid - 1;
else l = mid + 1;
}
printf("%d\n", ans);
}
int main () {
while (~scanf("%d%d", &n, &m) && (n + m)) run();
return 0;
}