Luo Gu CF161D

It can be said is the easiest one of the bar, with a barrel to record just fine.

#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; } 

As long as the previous learned how this problem should be over AC, just like me ^ _ ^

Guess you like

Origin www.cnblogs.com/syzf2222/p/12386770.html