跑的比谁都快 51Nod

香港记者跑的比谁都快是众所周知的常识。

 
现在,香港记者站在一颗有  nn 个点的树的根结点上(即1号点),编号为  ii 的点拥有权值  a[i]a[i] ,数据保证每个点的编号都小于它任意孩子结点的别号。
 
我们假定这棵树的每个叶子结点都在发生一个大新闻,香港记者要用最少的耗时去报道其中的任意一个。
 
若香港记者目前处于第  ii 号点上,那么它可以移动至以  ii 为根的子树上的任意一点  jj ,耗时 a[i]+(ji)pa[i]+(j−i)p ,p为给定常数。
 
请问这位香港记者搞哪个大新闻的耗时最短?所耗时间是多少?

Input第一行两个数n<=100000、p<=10,代表树上点的个数以及题中所提及的常数p。 
接下来n行,第i行有两个数字aii<10^6、faii <i,分别代表i号点的权值与i号点的父亲节点编号(根节点父亲编号为0)。

数据保证最短耗时不超过10^18.
Output每组数据输出一行为最短耗时。Sample Input

10 2
833 0
2076 1
5759 1
5671 3
6642 2
3712 4
8737 1
5139 6
8800 1
6638 1

Sample Output

849


先谢谢Jessie Liu大佬的点拨。
题解:
  这个题目,我们先考虑一条链的情况,设dp[i]表示i这个节点到1节点的最小花费,那么dp[i]=dp[j]+cost[j~i],这个是十分显然的,所以在链上枚举i的每个前驱节点就可以。
  换成一棵树,因为一棵树是由很多条链来组成的,对于节点i,我们可以枚举每个祖先来j来dp,状态转移是一样的,但是具体怎么在树上枚举祖先呢?可以开一个栈记录一下所经过的深度的节点就看了。
  因为是指数函数,可以看出有决策单调性,那么就记一下父节点是从哪里转移的,从那里开始枚举就可以了。

代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#define MAXN 100100
#define ll long long
using namespace std;
struct edge{
    int first;
    int next;
    int to;
}a[MAXN*2];
ll dp[MAXN],node[MAXN],fa[MAXN],stk[MAXN],last[MAXN],ans=1ll<<60;
int n,p,num=0;

void addedge(int from,int to){
    a[++num].to=to;
    a[num].next=a[from].first;
    a[from].first=num;
}

ll pw(ll base,int h){
    ll ans=1;
    while(h){
        if(h&1) ans=ans*base;
        base*=base;h>>=1;
    }
    return ans;
}

void dfs(int now,int dep){
    stk[dep]=now;
    for(int j=last[fa[now]];j<dep;j++){
        ll cnt=dp[stk[j]]+node[stk[j]]+pw(now-stk[j],p);
        if(dp[now]>cnt) dp[now]=cnt,last[now]=j;
    }
    int sz=0;
    for(int i=a[now].first;i;i=a[i].next){
        int to=a[i].to;
        if(to==fa[now]) continue;
        sz++;
        dfs(to,dep+1);
    }
    if(!sz) ans=min(ans,dp[now]);
}

int main()
{
    scanf("%d%d",&n,&p);
    memset(dp,37,sizeof(dp));
    for(int i=1;i<=n;i++){
        scanf("%lld%lld",&node[i],&fa[i]);
        addedge(i,fa[i]),addedge(fa[i],i);
    }
    dp[1]=0;
    dfs(1,0);
    printf("%lld",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/renjianshige/p/7573168.html