- 学术
【每日一题】洛谷P1272
- 2025-6-29 19:31:09 @
P1272 重建道路
题目描述
一场可怕的地震后,人们用 个牲口棚(编号 )重建了农夫 John 的牧场。由于人们没有时间建设多余的道路,所以现在从一个牲口棚到另一个牲口棚的道路是唯一的。因此,牧场运输系统可以被构建成一棵树。
John 想要知道另一次地震会造成多严重的破坏。有些道路一旦被毁坏,就会使一棵含有 个牲口棚的子树和剩余的牲口棚分离,John 想知道这些道路的最小数目。
输入格式
第一行两个整数, 和 。
第二行到第 行,每行两个整数 和 ,表示节点 是节点 的父节点。牧场运输系统可以被构建成一棵以 1 号节点为根的树。
输出格式
单独一行,包含一旦被破坏将分离出恰含 个节点的子树的道路的最小数目。
输入输出样例 #1
输入 #1
11 6
1 2
1 3
1 4
1 5
2 6
2 7
2 8
4 9
4 10
4 11
输出 #1
2
说明/提示
样例解释
如果道路 和 被破坏,含有节点()的子树将被分离出来。
限制与约定
,,保证给出的是一棵树。
参考代码
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
typedef long long LL;
const LL Maxn = 150 + 5;
const LL Inf = 1e18;
vector<LL> grid[Maxn];
LL res = Inf;
LL dfs(LL u, LL p, vector<vector<LL> >& dp) {
dp[u][1] = grid[u].size() + (u != 1);
LL sum = 1;
for (auto v : grid[u]) {
sum += dfs(v, p, dp);
for (LL i = min(sum, p); i > 1; --i) {
for (LL j = 1; j <= i; ++j)
dp[u][i] = min(dp[u][i], dp[u][i - j] + dp[v][j] - 2);
}
}
res = min(res, dp[u][p]);
return sum;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
LL n, p, u, v;
cin >> n >> p;
for (LL i = 1; i < n; ++i) {
cin >> u >> v;
grid[u].emplace_back(v);
}
vector<vector<LL> > dp(n + 1, vector<LL> (p + 1, Inf));
dfs(1, p, dp);
cout << res;
return 0;
}
0 条评论
目前还没有评论...