HDU2196computer(树上最远距离 + DP)
2016-02-15 12:39
239 查看
Computer
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4990 Accepted Submission(s): 2509
[align=left]Problem Description[/align]
A school bought the first computer some time ago(so this computer's id is 1). During the recent years the school bought N-1 new computers. Each new computer was connected to one of settled earlier. Managers of school are anxious about slow functioning of the net and want to know the maximum distance Si for which i-th computer needs to send signal (i.e. length of cable to the most distant computer). You need to provide this information.
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> using namespace std; const int Max = 10000 + 10; struct Node { int to,next,len; }; Node edge[2 * Max]; int head[Max], tol; int maxn[Max],maxnId[Max]; //最远距离和最远距离对应的序号 int smaxn[Max],smaxnId[Max]; //次远距离和次远距离对应的序号 void add_edge(int a, int b, int len) { edge[tol].to = b; edge[tol].next = head[a]; edge[tol].len = len; head[a] = tol++; } void dfs1(int u, int p) { maxn[u] = smaxn[u] = 0; for(int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if(v == p) //如果是父节点跳过 continue; dfs1(v, u); if(smaxn[u] < maxn[v] + edge[i].len) //如果子节点的最远距离大于次远距离,就更新次远距离;先更新次远距离,由次远距离和最远距离比较更新最远距离 { smaxn[u] = maxn[v] + edge[i].len; smaxnId[u] = v; if(smaxn[u] > maxn[u]) { swap(smaxn[u], maxn[u]); swap(smaxnId[u], maxnId[u]); } } } } 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; if(v == maxnId[u]) //如果父节点方向最远距离经过这个子节点 { if(smaxn[u] + edge[i].len > smaxn[v]) //选择次远距离,因为最远距离经过v点 { smaxn[v] = smaxn[u] + edge[i].len; smaxnId[v] = u; if(maxn[v] < smaxn[v]) { swap(maxn[v], smaxn[v]); swap(maxnId[v], smaxnId[v]); } } } else { if(maxn[u] + edge[i].len > smaxn[v]) { smaxn[v] = maxn[u] + edge[i].len; smaxnId[v] = u; if(maxn[v] < smaxn[v]) { swap(maxn[v], smaxn[v]); swap(maxnId[v], smaxnId[v]); } } } dfs2(v, u); } } int main() { int n,v,len; while(scanf("%d", &n) != EOF) { tol = 0; memset(head, -1, sizeof(head)); for(int i = 2; i <= n; i++) { scanf("%d%d", &v, &len); add_edge(i, v, len); add_edge(v, i, len); } dfs1(1, -1); //向下 dfs2(1, -1); for(int i = 1; i <= n; i++) printf("%d\n", maxn[i]); } return 0; }
View Code
相关文章推荐
- Swift 关于"/"和"%"
- 深入浅出 Android Support Annotation
- [C语言]查找链表的中间元素
- 忙些更好
- Oracle表值函数的两种写法
- JAVA应用程序获取当前路径
- hdu1298T9
- springmvc-servlet.xml中use-default-filters的作用
- HDU——1393Weird Clock(水题,注意题意)
- 静态区间第k大(分桶法和平方分割)
- 静态区间第k大(分桶法和平方分割)
- NDK 编译和使用静态库、动态库; Android.mk 文件语法详解; Android.mk高级写法
- mpg123 把mp3文件解码到标准输出设备(stdout)
- 从零开始山寨Caffe·贰:主存模型
- Handler 与 Looper
- Dolby(杜比)
- Laravel-lumen 配置JWT
- #学习笔记#(43)CSS-border绘制三角形
- Working with Streams 使用流
- 安装Microsoft Expression Blend 4 的时候,提示 需要重启系统