Computer HDU - 2196(树形dp)

题目要求:求树上每个点能到达的最远距离

dp[u][0]:u的子树下u的最远距离是多少

dp[u][1]:u的子树次远距离是多少

dp[u][2]:u的父亲能走的最远距离是多少

dp[0] [1]dfs处理即可

如果vi不是u最长距离经过的节点,f[vi][1] = dist(vi,u)+max(f[u][0], f[u][1])
如果vi是u最长距离经过的节点,那么不能选择f[u][0],因为这保存的就是最长距离,要选择u次大距离

#include<bits/stdc++.h>

#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;

const int maxn=1e5+10;

struct edge{
    int u,v,w,next;
}e[maxn];

int g[maxn],tot=0;

int dp[maxn][3];

void creat_edge(int u,int v,int w)
{
    e[++tot]=(edge){u,v,w,g[u]};
    g[u]=tot;
}

void dfs(int u)//递归求得u子树中的最大与次大 0最大 1次大
{
    for(int i=g[u];i>0;i=e[i].next)
    {
        int v=e[i].v;
        dfs(v);
        int w=e[i].w;
        int temp= dp[v][0]+w;
        if(temp>=dp[u][0])
        {
            dp[u][1]=dp[u][0];
            dp[u][0]=temp;
        }
        else if(temp>dp[u][1])
            dp[u][1]=temp;
    }
}

void dfs1(int u)
{
    for(int i=g[u];i>0;i=e[i].next)
    {
        int v=e[i].v,w=e[i].w;
        if(dp[u][0]==dp[v][0]+w)//如果当前节点在最大路径上 只能取次大路径
            dp[v][2]=max(dp[u][2],dp[u][1])+w;
        else
            dp[v][2]=max(dp[u][2],dp[u][0])+w;
        dfs1(v);
    }
}

int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        mem(g,0);
        mem(dp,0);
        for(int i=2;i<=n;i++)
        {
            int u=i,v,w;
            scanf("%d%d",&v,&w);
            creat_edge(v,u,w);
        // creat_edge(v,u,w);
        }
        dfs(1);
        dfs1(1);
        for(int i=1;i<=n;i++)
            cout<<max(dp[i][0],dp[i][2])<<"\n";
    }
    return 0;
}

原文地址:https://www.cnblogs.com/minun/p/10806651.html

时间: 2024-10-16 11:40:32

Computer HDU - 2196(树形dp)的相关文章

hdu 2196 树形dp

题意: 给你n太台电脑 及 相邻之间的 距离 让你求出 每台电脑的离它最远的电脑的离: 思路:树形dp,题意给出一棵树,求离每个节点最远的点的距离, 两种情况1,以该节点s作为根节点的子树中的离该节点最长距离x.2,其父树中离该节点的最长距离y.答案就是max(x, y); 需要注意的是:父树中的最长距离有可能经过s点, 这时候就要选父树中次长的路径(求第一种时顺便求出) ps:建图时是双向边  不明白在纸上画图走一遍样例 代码: #include <iostream> #include &l

hdu 4123 树形DP+RMQ

http://acm.hdu.edu.cn/showproblem.php?pid=4123 Problem Description Bob wants to hold a race to encourage people to do sports. He has got trouble in choosing the route. There are N houses and N - 1 roads in his village. Each road connects two houses,

hdu 1250 树形DP

Anniversary party Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Appoint description:  System Crawler  (2014-07-27) Description There is going to be a party to celebrate the 80-th Anniversary of the Ural St

hdu 4276(树形dp)

题意:带权树上有起点终点每个点上有宝藏,一个人只有T分钟要从起点到重点,问你最多能收集多少宝藏. 思路:树形dp,首先判断能不能走到终点,然后把路径上的边权变为0时间减去所有边权.dp[v][j]表示从v出发回到v话费j分钟最多能收集到的宝藏. dp[v][j] = max(dp[v][j], dp[x][k] + dp[v][j-k-2*val]); 被G++卡了好长时间,换成c++就过了. 代码如下: 1 #include <stdio.h> 2 #include <string.h

hdu 5148 树形dp+分组背包问题

http://acm.hdu.edu.cn/showproblem.php?pid=5148 Problem Description Long long ago,there is a knight called JayYe.He lives in a small country.This country is made up of n cities connected by n-1 roads(that means it's a tree).The king wants to reward Ja

HDU 1520 树形dp裸题

1.HDU 1520  Anniversary party 2.总结:第一道树形dp,有点纠结 题意:公司聚会,员工与直接上司不能同时来,求最大权值和 #include<iostream> #include<cstring> #include<cmath> #include<queue> #include<algorithm> #include<cstdio> #define max(a,b) a>b?a:b using nam

hdu 3586 树形dp+二分

题目大意:给定n个敌方据点,1为司令部,其他点各有一条边相连构成一棵 树,每条边都有一个权值cost表示破坏这条边的费用,叶子节点为前线.现要切断前线和司令部的联系,每次切断边的费用不能超过上限limit,问切断所 有前线与司令部联系所花费的总费用少于m时的最小limit.1<=n<=1000,1<=m<=100万 题目要问的是最小的最大限制,必然二分答案 然后对于每一个值,树形DP判定是否可行 dp[i]表示要切断以i为根的其它所有子树的最小代价. 其中设定叶子结点的代价为无穷大

HDU 1561 树形DP入门

The more, The Better Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 6011    Accepted Submission(s): 3555 Problem Description ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝物

hdu 1561 树形dp

又一道树形dp,发现其实树形dp长得都挺像的. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 const int INF = -9999999; 7 const int N = 201; 8 int dp[N][N]; 9 int head[N]; 10 int value[N]; 11 int n, m, e; 12 13 void i