luoguのP3254ツリー問題解決レポート

タイトル説明

この問題では、値Sと木を与えられました。ツリーの各ノードでの正の整数であり、Iは、加算ノードSに到達するためにどのように多くのパスを尋ねました ノードへのパスの深さは、昇順でなければなりません。ノードがルートノードであると仮定し、根の深さは、その子ノードの深さは1であり、0です。パスがルートから起動する必要はありません。
入力形式

Nは、ツリー内のノードの数であり、二つの整数NとSの最初の行。第二行は、正の整数N、iは正の整数を表し、i番目のノードの整数です。次のN-1ライン各Xは2の整数であり、yは、xがyは息子で表します。

出力フォーマット

出力パスノードSの和は、パスの数です。

サンプル入力と出力

入力:
。3. 3
。1 2 3
。1 2
。1。3
出力:
2

説明/ヒント

データの100%、N <= 100000、及び所有権の価値はない1000以上S.へ

問題の解決策

これは、ddタイトルです!
より多くのDD DDであることがよりがあります!
n個の正方形の上に直接、脳を移動する必要はありません
:キーポイント
1.ルートノード
の現在値がSブレイク2よりも大きい場合。

コード

#include <iostream>
#include <cstdio>
#define ll long long
#define R register
using namespace std;
inline int read(){
    int x=0,f=1;char c=getchar();
    while (c>'9'||c<'0') {if (c=='-') f=-1;c=getchar();}
    while (c>='0'&&c<='9') {x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    return x*f;
}
const int maxn=1e5+5;       
int s,n,ans;
int a[maxn],fa[maxn];

void init(){
    n=read(),s=read();
    for (R int i(1);i<=n;++i) a[i]=read(),fa[i]=i;
    for (R int i(1),x,y;i<n;++i) x=read(),y=read(),fa[y]=x;
}
inline int getroot(int u){
    if (fa[u]==u) return u;
    return getroot(fa[u]);
}
void doit(){
    int rt=getroot(1);
    for (R int i(1);i<=n;++i){
        int sum=a[i];
        if (sum==s) ans++;
        if (sum>s) continue;
        int j=i;
        while (j!=rt){
            j=fa[j];
            sum+=a[j];
            if (sum==s) ++ans;
            if (sum>s) break;
        }
    }
    printf("%d\n",ans);
}
int main(){
    init();
    doit();
    return 0;
}

おすすめ

転載: www.cnblogs.com/ancer/p/11316189.html