HDU 3848 CC On The Tree 树形DP
2016-04-05 19:15
302 查看
题意:
给出一棵边带权的树,求距离最近的一对叶子。分析:
通过DFS计算出\(min(u)\):以\(u\)为根的子树中最近叶子到\(u\)的距离。然后维护一个前面子树\(v_i\)中叶子到\(u\)距离的最小值,就可以用这个最小值+当前子树中叶子到\(u\)的最短距离来更新答案。
如果根节点也是叶子节点的话,再用\(min(root)\)更新一下答案。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 10000 + 10; const int INF = 0x3f3f3f3f; struct Edge { int v, w, nxt; Edge() {} Edge(int v, int w, int nxt): v(v), w(w), nxt(nxt) {} }; int ecnt, head[maxn]; Edge edges[maxn * 2]; void AddEdge(int u, int v, int w) { edges[ecnt] = Edge(v, w, head[u]); head[u] = ecnt++; edges[ecnt] = Edge(u, w, head[v]); head[v] = ecnt++; } int n; int ans; int minv[maxn]; int child[maxn]; void dfs(int u, int p) { minv[u] = INF; int minp = INF; child[u] = 0; for(int i = head[u]; ~i; i = edges[i].nxt) { int v = edges[i].v; if(v == p) continue; child[u]++; int w = edges[i].w; dfs(v, u); minv[u] = min(minv[u], minv[v] + w); ans = min(ans, minp + minv[v] + w); minp = min(minp, minv[v] + w); } if(!child[u]) minv[u] = 0; } int main() { while(scanf("%d", &n) == 1 && n) { ecnt = 0; memset(head, -1, sizeof(head)); for(int i = 1; i < n; i++) { int u, v, w; scanf("%d%d%d", &u, &v, &w); AddEdge(u, v, w); } ans = INF; dfs(1, 0); if(child[1] == 1) ans = min(ans, minv[1]); printf("%d\n", ans); } return 0; }
相关文章推荐
- Android 如何避免(降低)后台程序被杀?
- 哈希算法&&Java中的HashMap实现原理
- 立体匹配综述阅读心得之Classification and evaluation of cost aggregation methods for stereo correspondence
- 计算三角形面积
- redis持久化
- cxf把wsdl生成java文件
- js内存泄漏以及解决方案
- Palindrome Linked List/链表的回文结构
- 算法训练 乘法表
- 51nod 1060反素数
- LeetCode *** 111. Minimum Depth of Binary Tree
- c++智能指针
- hdu 1247 Hat’s Words
- J2EE 开发中遇到的问题
- 第五周项目3(1)
- git 学习1
- linux环境下的jdk安装配置
- 第六周项目二-带武器的游戏角色
- 构造器权限与类权限的问题
- 二分法查找