[Acm] foj 2195 : 檢查站點(樹的遍歷)

Problem 2195 檢查站點
Accept: 39 Submit: 106
Time Limit: 1000 mSec Memory Limit : 32768 KBios

Problem Descriptionspa

在山上一共有N個站點須要檢查,檢查員從山頂出發去各個站點進行檢查,各個站點間有且僅有一條通路,檢查員下山前往站點時比較輕鬆,而上山時卻須要額外的時間,問最後檢查員檢查完全部站點時所須要的額外時間最少是多少。設計

Inputcode

包含多組數據 每組數據輸入第一行爲一個整數N 表示站點個數(1<=N<=100000),接下去N-1 行 每行3個整數 x,y,z(1<=z<=10000) 檢查站x爲檢查站y的父節點,x,y之間有一條通路,從y到x須要額外z的時間。(父節點在子節點上方,山頂固定標號爲1)
Outputip

輸出一行一個整數表示最少須要花費的額外時間。
Sample Inputstring

6
1 2 1
2 4 1
1 3 1
3 5 1
3 6 1
Sample Outputit

3
Sourceio

福州大學第十二屆程序設計競賽程序設計


題意:

給你n個點,n-1條邊,每條邊有額外花費的時間。
如此構成一棵樹,1是根節點。
從父節點向子節點(從上到下)遍歷不會花費時間,回溯則要花費額外的時間。
求遍歷這棵樹的全部節點花費的最小時間。stream

思路:

由於最後一條邊不用回溯,因此找到這棵樹的額外時間花費總量最大一條路徑(從根節點到葉子節點),再用這棵樹的總額外時間 - 最大路徑的額外時間 就是遍歷全部節點的最小花費時間了。

代碼:

#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;

#define MAXN 100010

int par[MAXN];      //該節點的父節點
bool Hash[MAXN];    //該節點是不是父節點,初始化所有不是父節點
int val[MAXN];      //以x爲子節點的通路價值

int main()
{
    int n,x,y,z,i;
    while(scanf("%d",&n)!=EOF){
        memset(par,0,sizeof(par));
        memset(Hash,0,sizeof(Hash));
        memset(val,0,sizeof(val));
        //讀入,建樹
        int Sum = 0,Max = 0;
        for(i=1;i<=n-1;i++){
            scanf("%d%d%d",&x,&y,&z);
            par[y] = x;
            Hash[x] = true;
            val[y] = z;
            Sum+=z;
        }
        for(i=1;i<=n;i++){
            if(!Hash[i]){   //是葉子節點
                int now = i,t=0;
                while(now!=1){  //向上尋找到根節點
                    t += val[now];
                    now = par[now];
                }
                if(t>Max)
                    Max = t;
            }
        }
        printf("%d\n",Sum-Max);
    }
    return 0;
}
相關文章
相關標籤/搜索