SGU 149 Computer Network(树形DP)

来源:互联网 发布:现在做淘宝 编辑:程序博客网 时间:2024/05/04 01:57

题目链接:点击打开链接

题目大意:给出从2~n号节点的父节点与其和父节点的距离,输出每个节点到树中节点的最大距离。

解题思路:第一遍DFS,用deep[i][0]记录节点i到其子节点的最大距离,deep[i][1]保存次大距离。

第二遍DFS,deep[i][0]的意义变成了节点i到树中节点的最大距离,deep[i][1]为次大距离。由于根节点1的deep[1][0]表示的就是距离树中节点的最大距离,所以可以从1开始向下变遍历,使用父节点的deep来更新当前节点的deep。具体更新的规则是:若子节点v在父节点u到最远节点的路径上,就用deep[u][1](也就是次大距离)+|<u,v>|(u到v的距离)来更新deep[v]


若不在,则使用deep[u][0](也就是最大距离)+|<u,v>|(u到v的距离)来更新deep[v]。



通过deep[u][0] == deep[v][0]+|<u,v>|来判断v是否在路径上。最后输出所有的deep[i][0]。


#include <set>#include <map>#include <cmath>#include <stack>#include <queue>#include <vector>#include <string>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;typedef long long LL;#define FIN freopen("in.txt", "r", stdin);#define FOUT freopen("out.txt", "w", stdout);#define lson l, mid, cur << 1#define rson mid + 1, r, cur << 1 | 1const int INF = 0x3f3f3f3f;const int MAXN = 1e5 + 50;const int MOD = 1e9 + 7;int n, dis[MAXN], deep[MAXN][2];struct Edge{    int u, v, val, nxt;}E[MAXN];int Head[MAXN], erear;void edge_init(){    erear = 0;    memset(Head, -1, sizeof(Head));}void edge_add(int u, int v, int val){    E[erear].u = u;    E[erear].v = v;    E[erear].val = val;    E[erear].nxt = Head[u];    Head[u] = erear++;}int dfs1(int u, int f){    for (int i = Head[u]; ~i; i = E[i].nxt)    {        int v = E[i].v;        if (v == f)            continue;        int tmpdeep = dfs1(v, u) + E[i].val;        if (tmpdeep > deep[u][0])            swap(tmpdeep, deep[u][0]);        if (tmpdeep > deep[u][1])            swap(tmpdeep, deep[u][1]);    }    return deep[u][0];}void dfs2(int u, int f){    for (int i = Head[u]; ~i; i = E[i].nxt)    {        int v = E[i].v;        if (v == f)            continue;        int tmpdeep;        if (deep[u][0] == deep[v][0] + E[i].val)            tmpdeep = deep[u][1] + E[i].val;        else            tmpdeep = deep[u][0] + E[i].val;        if (tmpdeep > deep[v][0])            swap(tmpdeep, deep[v][0]);        if (tmpdeep > deep[v][1])            swap(tmpdeep, deep[v][1]);        dfs2(v, u);    }}int main(){#ifndef ONLINE_JUDGE    FIN;#endif // ONLINE_JUDGE    while (~scanf("%d", &n))    {        edge_init();        for (int i = 2; i <= n; i++)        {            int v, val;            scanf("%d%d", &v, &val);            edge_add(v, i, val);            edge_add(i, v, val);        }        memset(deep, 0, sizeof(deep));        dfs1(1, -1);        dfs2(1, -1);        for (int i = 1; i <= n; i++)            printf("%d\n", deep[i][0]);    }    return 0;}


1 0