1472. Martian Army

http://acm.timus.ru/problem.aspx?space=1&num=1472ios

題目大意:測試

一顆樹,根節點(1) 的值爲 1.0,全部葉子節點的值爲 0.0 ,其餘節點值任意spa

最後要求的是 全部相鄰兩個節點的值差的總和最小。blog

思路:遞歸

假設一個葉子節點爲 c ,他的父節點爲 b ,b的父節點爲 a,那麼 c 的值爲 0.0,get

此子樹的最優結果爲 (value[a]-value[b])*cost[a->b] + (value[b]-value[c])*cost[b->c] 的最小值string

由於value[c]=0.0 肯定,那麼value[b]的值要麼爲 0.0 要麼爲value[a] 這要取決於 cost[a->b] 和 cost[b->c]io

的大小關係,value[] 差值爲0的那一段能夠去掉,而後若是a還有其餘枝葉,要累加。class

而後以這種思想逐步向上遞歸,直到根節點。看代碼能夠一目瞭然。stream

剛開始一直WA9,後來把多組輸入改爲單組就對了,URAL上的題多數爲單組數據測試,但平時寫的時候爲了本身測試方便

就習慣寫成多組的,通常也不會出問題,這題的第9組測試數據,應該是有多餘的數據在最後,全部纔會出錯。

代碼: 

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>

using namespace std;

const int INF=0x3f3f3f3f;
const int N=100005;
int k[N],c[N];
int dp[N];
bool loaf[N];
int main()
{
    //freopen("data.in","r",stdin);
    int n;
    scanf("%d",&n);
    memset(loaf,true,sizeof(loaf));
    for(int i=2;i<=n;++i)
    {
        scanf("%d %d",&k[i],&c[i]);
        loaf[k[i]]=false;
    }
    for(int i=1;i<=n;++i)
    if(loaf[i]) dp[i]=INF;
    else dp[i]=0;
    for(int i=n;i>=2;--i)
    dp[k[i]]+=min(dp[i],c[i]);
    printf("%.2f\n",(double)dp[1]);
    return 0;
}
相關文章
相關標籤/搜索