萌新求助QAQ
查看原帖
萌新求助QAQ
365236
岚默笙楼主2021/3/16 15:03

做法是t[i]表示到根距离为i的最小边数 A了两个点,剩下的都是TLE 代码如下

#include<bits/stdc++.h>
using namespace std;
#define y to[i]
const int maxn=2e6+10;
int head[maxn],to[maxn<<1],val[maxn<<1],nxt[maxn<<1],tot=0;
int n,k;
void add(int x,int c,int z)
{
	to[++tot]=c;
	nxt[tot]=head[x];
	head[x]=tot;
	val[tot]=z;
}
int ans=0x7f7f7f7f;
int vis[maxn];
int t[1000010];
int sz[maxn],tsz,maxp[maxn],rt;
void getroot(int x,int f)
{
	sz[x]=1;
	maxp[x]=0;
	for(int i=head[x];i;i=nxt[i])
	{
		if(vis[y]||y==f)
		continue;
		getroot(y,x);
		sz[x]+=sz[y];
		maxp[x]=max(maxp[x],sz[y]);
	}
	maxp[x]=max(maxp[x],tsz-sz[x]);
	if(maxp[x]<maxp[rt])
	rt=x;
}
void dfs_calc(int x,int f,int dep,int dis)
{
	if(dis>k)return;
	if(t[k-dis]!=2139062143)
	ans=min(ans,dep+t[k-dis]);
	for(int i=head[x];i;i=nxt[i])
	{
		if(vis[y]||y==f)
		continue;
		dfs_calc(y,x,dep+1,dis+val[i]);
	}
}
void dfs_put(int x,int f,int dep,int dis)
{
	if(dis>k) return;
	t[dis]=min(t[dis],dep);
	for(int i=head[x];i;i=nxt[i])
	{
		if(y==f||vis[y])
		continue;
		dfs_put(y,x,dep+1,dis+val[i]);
	}
}
void calc(int x)
{
	t[0]=0;
	for(int i=head[x];i;i=nxt[i])
	{
		if(vis[y])
		continue;
		dfs_calc(y,x,1,val[i]);
		dfs_put(y,x,1,val[i]);		
	}
}
void divide(int x)
{
	calc(x);
	vis[x]=1;
	for(int i=head[x];i;i=nxt[i])
	{
		if(vis[y])continue;
		rt=0;
		tsz=sz[y];
		memset(t,0x3f,sizeof(t));
		getroot(y,0);
		divide(rt);		
	}
} 
int main()
{
	memset(t,0x3f,sizeof(t));
	t[0]=0;
	scanf("%d%d",&n,&k);
	for(int i=1;i<n;i++)
	{
		int x,c,z;
		scanf("%d%d%d",&x,&c,&z);
		x++,c++;
		add(x,c,z);
		add(c,x,z);
	}	
	rt=0;
	
	maxp[0]=0x7f7f7f7f;
	tsz=n;
	getroot(1,0);
	divide(rt);
	if(ans==2139062143)
	printf("-1\n");
	else 
	printf("%d\n",ans);
	return 0;
}
2021/3/16 15:03
加载中...