洛谷CF161D

这可以说是最简单的一道了吧,用一个桶去记录就好了。

#include<bits/stdc++.h>
using namespace std;
const int maxn=100000+10;
#define inf 1e9
int n,k;
int beg[maxn],nex[maxn],to[maxn],w[maxn],e;
void add(int x,int y,int z){
    e++;nex[e]=beg[x];
    beg[x]=e;to[e]=y;w[e]=z;
}
int mx,size,rt;
int sz[maxn],son[maxn],vis[maxn];
inline void getrt(int x,int fa){
    sz[x]=1,son[x]=0;
    for(int i=beg[x];i;i=nex[i]){
        int t=to[i];
        if(vis[t]||t==fa)continue;
        getrt(t,x);
        sz[x]+=sz[t];
        if(son[x]<sz[t])son[x]=sz[t];
    }
    if(son[x]<size-sz[x])son[x]=size-sz[x];
    if(son[x]<mx)mx=son[x],rt=x;
}
int top,q[maxn],ans;
inline void stk(int x,int fa,int val){
    if(val>k)return;
    if(val==k){
        ans++;
        return;
    }
    q[++top]=val;
    for(int i=beg[x];i;i=nex[i]){
        int t=to[i];
        if(t==fa||vis[t])continue;
        stk(t,x,val+w[i]);
    }
}
inline void divide(int x){
    int bot[500+10]={0};
    vis[x]=1;
    for(int i=beg[x];i;i=nex[i]){
        int t=to[i];
        if(vis[t])continue;
        top=0;stk(t,x,w[i]);
        for(int i=1;i<=top;i++)
            ans+=bot[k-q[i]];
        for(int i=1;i<=top;i++)
            bot[q[i]]++;
        mx=inf,size=sz[t],rt=0;
        getrt(t,x);
        divide(rt);
    }
}
int main(){
    cin>>n>>k;
    int x,y,z;
    for(int i=1;i<n;i++){
        scanf("%d%d",&x,&y);
        add(x,y,1);add(y,x,1);
    }
    mx=inf,size=n,rt=0;
    getrt(1,0);
    divide(rt);
    printf("%d\n",ans);
    return 0;
} 

只要前面学懂了,这题应该要一遍AC,就像我一样^_^

posted @ 2020-02-29 22:47  syzf2222  阅读(115)  评论(0编辑  收藏  举报