HDU 2196 Computer(树形dp)

9 篇文章 0 订阅

OJ题目 : 猛戳~~

大概题意:给出所有节点 与 所连接节点之间的距离, 求节点到其他节点之间的最远距离

AC_CODE

#include <iostream>
#include <string>
#include <string.h>
#include <map>
#include <stdio.h>
#include <algorithm>
#include <queue>
#include <vector>
#include <math.h>
#include <set>
#include <list>
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define Max_N 10008

using namespace std ;
typedef long long LL ;

struct Edge
{
    int v;//与之连接的点
    int w;//长度
    Edge(){}
    Edge(int i,int j):v(i),w(j){}
};

int N;
vector<Edge> List[Max_N];
int longest_length[Max_N], longest_id[Max_N];
int sec_length[Max_N], sec_id[Max_N];

void dfs_1(int u,int father)//求u节点与其叶子节点之间的最远和次远距离
{
    int v , w;
    for(int i = 0;i < List[u].size();i++)
    {
        v = List[u][i].v;
        w = List[u][i].w;
        if(v == father)
            continue;
        dfs_1(v , u);
        if(sec_length[u] < longest_length[v] + w)
        {
            sec_length[u] = longest_length[v] + w;
            sec_id[u] = v;
        }
        if(longest_length[u] < sec_length[u])
        {
            swap(sec_length[u] , longest_length[u]);
            swap(sec_id[u] , longest_id[u]);
        }
    }
}

void dfs_2(int u,int father)//求u节点与所有节点的最远和次远距离
{
    int v,w;
    for(int i = 0;i < List[u].size();i++)
    {
        v = List[u][i].v;
        w = List[u][i].w;
        if(v == father)
            continue;
        if(v == longest_id[u])
        {
            if(sec_length[v] < sec_length[u] + w)
            {
                sec_length[v] = sec_length[u] + w;
                sec_id[v] = u;
            }
            if(longest_length[v] < sec_length[v])
            {
                swap(longest_length[v] , sec_length[v]);
                swap(longest_id[v] , sec_id[v]);
            }
        }
        else
        {
            if(sec_length[v] < longest_length[u] + w)
            {
                sec_length[v] = longest_length[u] + w;
                sec_id[v] = u;
            }
            if(longest_length[v] < sec_length[v])
            {
                swap(longest_length[v] , sec_length[v]);
                swap(longest_id[v] , sec_id[v]);
            }
        }
        dfs_2(v , u);
    }
}
int main()
{

    while(cin >> N)
    {
        memset(longest_length , 0 , (N + 2)*sizeof(int));
        memset(sec_length , 0 , (N + 2)*sizeof(int));
        int u ,v ,w;
        for(int i = 0;i <= N;i++) List[i].clear();
        for(u = 2;u <= N;u++)
        {
            scanf("%d%d",&v ,&w);
            List[u].push_back(Edge(v , w));
            List[v].push_back(Edge(u , w));
        }
        dfs_1(1 , -1);
        dfs_2(1 , -1);
        for(int i = 1;i <= N;i++)
            cout << longest_length[i] << endl;
    }
    return 0;
}
这种题,肯定也是抱大腿的嘛~~~ 点我就去啦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值