ツリーのCF161D距離|点線のルール

効果の対象に

ツリーへのN個の入力ポイント

ツリー長のシーク経路の数は正確にKであります

入力形式

このような問題の意味として最初の2つの行番号N、K、

次のN-1ライン、各ライン二つの整数uは、vが木のエッジを表す(U、V)

出力フォーマット

このような問題の意味として整数ANS、


直接設定したテンプレート、何も言うこと

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<iostream>
#include<map>
using namespace std;
inline int read(){
    int x=0,f=1; char c=getchar();
    while(c<'0'||c>'9'){ if(c=='-')f=-1; c=getchar(); }
    while('0'<=c&&c<='9'){ x=x*10+c-'0'; c=getchar(); }
    return x*f;
}
const int N=5e4+10;
int nxt[N<<1],head[N],go[N<<1],tot;
inline void add(int u,int v){
    nxt[++tot]=head[u]; head[u]=tot; go[tot]=v;
    nxt[++tot]=head[v]; head[v]=tot; go[tot]=u; 
}
bool vis[N];
int n,k,size[N],sum,rt,maxp;
inline void getrt(int u,int fa){
    size[u]=1; int Max=0;
    for(int i=head[u];i;i=nxt[i]){
        int v=go[i];
        if(v==fa||vis[v])continue;
        size[u]+=size[v];
        Max=max(Max,size[v]);
    }
    Max=max(Max,sum-size[u]);
    if(Max<maxp)maxp=Max,rt=u;
}
int judge[N],rem[N],dis[N];
inline void getdis(int u,int fa){
    if(dis[u]>k)return;
    rem[++rem[0]]=dis[u];
    for(int i=head[u];i;i=nxt[i]){
        int v=go[i];
        if(v==fa||vis[v])continue;
        dis[v]=dis[u]+1;
        getdis(v,u);
    }
}
long long ans=0;
inline void calc(int u){
    for(int i=head[u];i;i=nxt[i]){
        int v=go[i];
        if(vis[v])continue;
        rem[0]=0; dis[v]=1; getdis(v,u);
        for(int i=1;i<=rem[0];i++)ans+=judge[k-rem[i]];
        for(int i=1;i<=rem[0];i++)judge[rem[i]]++;
    }
    for(int i=0;i<=n;i++){
        if(!judge[i])break;
        judge[i]=0;
    }
}
inline void solve(int u){
    judge[0]=vis[u]=1; calc(u);
    for(int i=head[u];i;i=nxt[i]){
        int v=go[i];
        if(vis[v])continue;
        sum=maxp=size[v]; getrt(v,0);
        solve(rt);
    }
}
signed main(){
    n=read(),k=read();
    for(int i=1;i<n;i++)add(read(),read());
    sum=maxp=n; getrt(1,0);
    solve(rt);
    cout<<(ans>>1)<<endl;
}

おすすめ

転載: www.cnblogs.com/naruto-mzx/p/12142166.html