首页 > 代码库 > HDU 2196 Computer

HDU 2196 Computer

http://acm.hdu.edu.cn/showproblem.php?pid=2196

题意:

给出一棵树,求出每个点到其他点的最远距离。

 

思路:
对于每一个点,一方面它可以往它的子树方向走,另一方面可以往父亲结点的方向走。所以我们需要两次dfs,第一次用来求出每个点往其子树方向的最远距离和次远距离,为什么要计算出次远距离呢,因为在第二次dfs求父亲结点方向时,可能父亲结点的最大值经过了这个点,此时需要更换路线使得它不经过这个点。

#include<iostream> #include<cstring>#include<string>#include<algorithm>#include<vector>using namespace std;#define N 10001int n;struct node{    int to;    //终点    int next;  //下一条同样起点的边    int w;     //权值}edge[N*2];int tol;int head[N];  //头结点,邻接链表存储int dist[N][3];   //dist[N][0]代表正向最远距离,[N][1]代表正向次远距离,[N][2]代表反向最远距离int flag[N];//邻接链表存储,加入到链表的首部void add_edge(int u, int v, int w){    edge[tol].to = v;    edge[tol].w = w;    edge[tol].next = head[u];    head[u] = tol++;    edge[tol].to = u;    edge[tol].w = w;    edge[tol].next = head[v];    head[v] = tol++;}int dfs1(int u, int fa){    if (dist[u][0] != -1)  return dist[u][0];    dist[u][0] = dist[u][1] = 0;        for (int e = head[u]; e != -1; e = edge[e].next)    {        int v = edge[e].to;        if (v == fa)   continue;        dfs1(v, u);        if (dist[u][0] < dist[v][0] + edge[e].w)        {            flag[u] = v;            dist[u][1] = dist[u][0];               //更新次远距离            dist[u][0] = dist[v][0] + edge[e].w;   //更新最远距离        }        //这个不能忘,比最远距离小但可能比次远距离大,此时需要更新次远距离        else if (dist[u][1] < dist[v][0] + edge[e].w)            dist[u][1] = dist[v][0] + edge[e].w;    }    return dist[u][0];}void dfs2(int u, int fa){    for (int e = head[u]; e != -1; e = edge[e].next)    {        int v = edge[e].to;        if (v == fa)  continue;        if (v == flag[u])  dist[v][2] = max(dist[u][2], dist[u][1]) + edge[e].w;        else dist[v][2] = max(dist[u][2], dist[u][0]) + edge[e].w;        dfs2(v, u);    }}int main(){    //freopen("D:\\txt.txt", "r", stdin);    int v, w;    while (~scanf("%d", &n) && n)    {        tol = 0;        memset(head, -1, sizeof(head));        memset(dist, -1, sizeof(dist));        memset(flag, -1, sizeof(flag));        for (int i = 2; i <= n; i++)        {            scanf("%d%d", &v, &w);            add_edge(i, v, w);    //存边        }        dfs1(1, -1);        dfs2(1, -1);        for (int i = 1; i <= n; i++)            printf("%d\n", max(dist[i][0], dist[i][2]));    }    return 0;}

 

HDU 2196 Computer