sgu149:Computer Network
2014-11-30 11:54
176 查看
题意:
给出一颗N个点的树,并分别给出其(N-1)条边的长度。要求每一个点到它树上的最远点的距离。
分析:
对于树中的每一个点,它到的最远点要么是它的子树的叶子节点,要么是祖先的异于该结点的儿子的子树上。
好像有点绕,其实也就是“往下走”与“往上再往下走”两种情况。
遍历一棵树,我们统计该结点子树上与其距离最远的结点所在儿子子树编号num[]及其距离maxl[],以及次远的距离_maxl[](作用后面讲)。
再枚举树上的每个结点i:
①:往下走答案即为maxl[i];
②:往上走,假设已走到了其祖先k,我们假定k此时为由往上走变为往下走的转折点:
(1)如果i不在num[k]的子树中,那么此时用maxl[k]+dis[i][k]来更新答案;
(2)如果i在num[k]的子树中,很明显就不能用maxl[k]来更新答案,此时用_maxl[k]+dis[i][k]来更新答案;
遍历树的时间为n,枚举+查询时间为nlogn,故总的时间复杂度为O(nlogn)。
给出一颗N个点的树,并分别给出其(N-1)条边的长度。要求每一个点到它树上的最远点的距离。
分析:
对于树中的每一个点,它到的最远点要么是它的子树的叶子节点,要么是祖先的异于该结点的儿子的子树上。
好像有点绕,其实也就是“往下走”与“往上再往下走”两种情况。
遍历一棵树,我们统计该结点子树上与其距离最远的结点所在儿子子树编号num[]及其距离maxl[],以及次远的距离_maxl[](作用后面讲)。
再枚举树上的每个结点i:
①:往下走答案即为maxl[i];
②:往上走,假设已走到了其祖先k,我们假定k此时为由往上走变为往下走的转折点:
(1)如果i不在num[k]的子树中,那么此时用maxl[k]+dis[i][k]来更新答案;
(2)如果i在num[k]的子树中,很明显就不能用maxl[k]来更新答案,此时用_maxl[k]+dis[i][k]来更新答案;
遍历树的时间为n,枚举+查询时间为nlogn,故总的时间复杂度为O(nlogn)。
#include <cstdio> #include <cstdlib> #include <algorithm> using namespace std; const int MAXN = 10005; int n = 0; struct al//Adjacency_list { int node, len; al *next; }*v[MAXN] = {NULL}, *t[MAXN] = {NULL}; int maxl[MAXN] = {0}, num[MAXN] = {0}, _maxl[MAXN] = {0}; int vis[MAXN] = {0}, top = 0; int fa[MAXN] = {0}, dis[MAXN] = {0}; void add(int x, int y, int d) { al *tmp; tmp = (al *)malloc(sizeof(al)); tmp->node = y; tmp->len = d; tmp->next = NULL; if(v[x] == NULL) v[x] = t[x] = tmp; else { t[x]->next = tmp; t[x] = tmp; } } void dfs(int x) { vis[x] = ++top; for(al *i = v[x]; i != NULL; i = i->next) if(!vis[i->node]) { fa[i->node] = x; dis[i->node] = i->len; dfs(i->node); if(maxl[x] < maxl[i->node]+i->len) { maxl[x] = maxl[i->node]+i->len; num[x] = i->node; } } for(al *i = v[x]; i != NULL; i = i->next) if(vis[x] < vis[i->node] && i->node != num[x]) _maxl[x] = max(_maxl[x], maxl[i->node]+i->len); } int main() { scanf("%d", &n); for(int i = 2; i <= n; ++i) { int x, y; scanf("%d%d", &x, &y); add(i, x, y);add(x, i, y); } dfs(1); for(int i = 1; i <= n; ++i) { int maxd = maxl[i], sum = 0; for(int j = i; j; j = fa[j]) { sum += dis[j]; if(num[fa[j]] != j) maxd = max(maxd, sum+maxl[fa[j]]); else maxd = max(maxd, sum+_maxl[fa[j]]); } printf("%d\n", maxd); } return 0; }
相关文章推荐
- sgu 149 Computer Network 树形dp
- SGU 149 树形DP Computer Network
- SGU 149 Computer Network 树DP/求每个节点最远端长度
- sgu 149 Computer Network
- sgu 149 分类: sgu 2015-04-12 12:47 26人阅读 评论(0) 收藏
- sgu 149
- SGU 149 Computer Network(树形DP)
- [SGU - 149 Computer Network] 树形DP 求带权树上每个节点的最长路长度
- sgu 149解题记录
- SGU 149 Computer Network [树形DP]
- SGU 149 Computer Network(树形DP)
- SGU 149 Computer Network 树状DP求单点到树的最大距离
- 深入浅出C# 中文版 图文皆译 第四章 类型和引用 page149
- reactos操作系统实现(149)
- 【sgu】107 解题报告
- 求解两数和是素数——sgu231
- NetBeans 时事通讯(刊号 # 149 - Jun 08, 2011)
- 高精度——sgu112
- SGU116
- SGU 123 The sum