点分治假掉求助,悬关
查看原帖
点分治假掉求助,悬关
569235
w9095楼主2023/8/1 17:04

TLE on #11

#include <bits/stdc++.h>
using namespace std;
struct edge
{
	long long v,next;
}e[500010];
long long n,k,u,v,s[500010],h[500010],d[500010],f[500010],g[500010],del[500010],he=0,cnt=0,ans=99999999,tol=0;
void add_edge(long long u,long long v)
{
	e[++cnt].next=h[u];
	e[cnt].v=v;
	h[u]=cnt;
}

long long cal(long long root,long long pre)
{
    long long sum=1;
    if(del[root])return 0;
    for(long long i=h[root];i;i=e[i].next)
        if(e[i].v!=pre)sum+=cal(e[i].v,root);
    return sum;
}

long long dfs(long long root,long long pre,long long cnt)
{
    long long maxn=0;
    if(del[root])return 0;
    for(long long i=h[root];i;i=e[i].next)
        if(e[i].v!=pre)
            {
            long long z=dfs(e[i].v,root,cnt);
            s[root]+=z,maxn=max(maxn,z);
            }
    if(max(maxn,cnt-s[root])<ans)ans=min(ans,max(maxn,cnt-s[root])),he=root;
    return s[root];
}

void count(long long now,long long pre)
{
	if(del[now])return;
	if(k-d[now]>=0)tol+=g[k-d[now]],f[d[now]]++;
	for(long long i=h[now];i;i=e[i].next)
	    if(e[i].v!=pre)
	      {
	      d[e[i].v]=d[now]+1;
		  count(e[i].v,now);
	      }
}

void dfz(long long now)
{
	if(del[now])return;
	ans=99999999;
	long long num=cal(now,0);
	long long debug=tol;
	for(long long i=0;i<=n;i++)s[i]=1,f[i]=g[i]=d[i]=0;
	dfs(now,0,num);
	g[0]++;
	for(long long i=h[he];i;i=e[i].next)
	    {
	    d[e[i].v]=1;
	    count(e[i].v,he);
	    for(long long i=0;i<=k;i++)
	        g[i]+=f[i],f[i]=0;
	    }
	del[he]=1;
	for(long long i=h[he];i;i=e[i].next)dfz(e[i].v);    
}

int main()
{
    scanf("%lld%lld",&n,&k);
    for(long long i=1;i<=n-1;i++)
        {
        	scanf("%lld%lld",&u,&v);
        	add_edge(u,v);add_edge(v,u);
		}
	dfz(1);
	printf("%lld",tol);
	return 0;
}
2023/8/1 17:04
加载中...