POJ 2378 Tree Cutting——树形dp

网友投稿 560 2022-11-28

POJ 2378 Tree Cutting——树形dp

POJ 2378 Tree Cutting——树形dp

题意:给定一棵树,现在要求删除一个点,使得删除这个点后得到的每个子树的节点数都少于总结点数的一半,并输出这个点,多个的话按从小到大的顺序全部输出

思路:类似于找数的重心

#include #include #include #include using namespace std;const int INF = 0x3f3f3f3f;const int maxn = 1e4 + 10;int n, tot, head[maxn], dp[maxn][3];struct Edge { int to, next;}edge[maxn<<1];void init() { tot = 0; memset(head, -1, sizeof(head)); memset(dp, 0, sizeof(dp));}void addedge(int u, int v) { ++tot; edge[tot].to = v, edge[tot].next = head[u]; head[u] = tot;}void dfs1(int u, int p) { dp[u][0] = 1; for (int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if (v == p) continue; dfs1(v, u); dp[u][0] += dp[v][0]; dp[u][1] = max(dp[u][1], dp[v][0]); }}void dfs2(int u, int p) { for (int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if (v == p) continue; dp[v][2] = dp[u][2] + dp[u][0] - dp[v][0]; dfs2(v, u); }}int main() { while (~scanf("%d", &n)) { init(); int u, v; for (int i = 1; i <= n - 1; i++) { scanf("%d %d", &u, &v); addedge(u, v); addedge(v, u); } dfs1(1, -1); dfs2(1, -1); for (int i = 1; i <= n; i++) { if (max(dp[i][1], dp[i][2]) <= n / 2) printf("%d\n", i); } } return 0;}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:解析spring boot与ireport 整合问题
下一篇:使用ServletInputStream在拦截器或过滤器中应用后重写
相关文章

 发表评论

暂时没有评论,来抢沙发吧~