hdu 2196 Computer(树上最长路)

题意是给定一棵树,求以每个点为起点所能得到的最长路。。。校赛的时候moonlight出了一个不固定起始点的树上最长路,当时没想法,赛后A了,没想到今天这个还是卡了很久。。。

求树上不固定起始点的最长路,两次dfs即可,第一次求到的最长路的终点必在最长路上,第二次dfs以其作为起始点就行。。。而这个题,求所有点为起点的最长路,任然需要两次dfs求出最长路及其两个端点,然后再来一次dfs,更新每个节点的最大距离就行。最近开始用宏定义了,感觉宏这个东西,看着挺恶心的,但是效果呢,谁用谁知道!

#include<iostream>
#include<algorithm>
#include<vector>
#include<cstdio>
#include<cstring>
using namespace std;

#define FF(i, a, b) for(int i=a; i<=b; i++)
#define FD(i, a, b) for(int i=a; i<=b; i--)
#define clr(a, b) memset(a, b, sizeof(a))
const int maxn = 10010;
int ans[maxn], n, end, max_len;
struct Edge
{
    int to, dist;
};
vector<Edge> edges;
vector<int> G[maxn];

void add(int from, int to, int dist)
{
    Edge x;
    x.to =  to, x.dist = dist;
    edges.push_back(x);
    x.to = from;
    edges.push_back(x);
    int k = edges.size();
    G[from].push_back(k-2);
    G[to].push_back(k-1);
}

inline void init()
{
    clr(ans, 0); max_len = 0;
    edges.clear();
    FF(i, 0, n) G[i].clear();
}

void dfs(int u, int fa, int len)
{
    int nc = G[u].size();
    if(len > max_len)   max_len = len, end = u;
    FF(i, 0, nc-1)
    {
        int v = edges[G[u][i]].to, w = edges[G[u][i]].dist;
        if(v != fa)
        {
            dfs(v, u, len + w);
            ans[v] = max(ans[v], len + w);
        }
    }
}

int main()
{
    while(~scanf("%d", &n))
    {
        init();
        int a, b;
        FF(i, 2, n)
        {
            scanf("%d%d", &a, &b);
            add(i, a, b);
        }
        dfs(1, -1, 0);
        dfs(end, -1, 0);
        dfs(end, -1, 0);
        FF(i, 1, n)
            printf("%d\n", ans[i]);
    }
    return 0;
}



你可能感兴趣的:(hdu 2196 Computer(树上最长路))