Mn Zn求助
查看原帖
Mn Zn求助
95244
tommymio楼主2021/2/20 08:42

RT,本题我使用 dsu on tree\text{dsu on tree} 算法,获得了 90 pts\text{90 pts} 的好成绩,有没有神仙路过救救孩子/kel

https://www.luogu.com.cn/record/46782252

#include<cstdio>
#include<map>
const int inf=0x3f3f3f3f;
typedef long long ll;
int Rt,Son;
int cnt,lim,ans=inf;
std::map<ll,int> buc;
ll sum[200005];
int h[200005],to[400005],ver[400005],w[400005];
int dep[200005],size[200005],son[200005];
inline int read() {
	register int x=0,f=1;register char s=getchar();
	while(s>'9'||s<'0') {if(s=='-') f=-1;s=getchar();}
	while(s>='0'&&s<='9') {x=x*10+s-'0';s=getchar();}
	return x*f;
}
inline int min(const int &x,const int &y) {return x<y? x:y;}
inline void add(int x,int y,int z) {to[++cnt]=y;ver[cnt]=h[x];w[cnt]=z;h[x]=cnt;}
inline void dfs1(int x,int fa) {
	size[x]=1;
	for(register int i=h[x];i;i=ver[i]) {
		int y=to[i]; if(y==fa) continue;
		dep[y]=dep[x]+1; sum[y]=sum[x]+w[i];
		dfs1(y,x); size[x]+=size[y];
		if(size[son[x]]<size[y]) son[x]=y; 
	}
} 
inline void upd(int x,int fa,int d) {
	//sum[x]-sum[Rt]+(sum[y_1]-sum[Rt])=lim
	//printf("%d %d %d %d %d %d %d %d %d\n",tmp,Rt,sum[Rt],sum[x]-sum[Rt],buc[tmp],dep[Rt],dep[x],buc[tmp]-dep[Rt]+dep[x]-dep[Rt]); 
	ll tmp=lim-(sum[x]-sum[Rt])+sum[Rt];
	if(d>0) {
		if(tmp>0&&buc.find(tmp)!=buc.end()) {ans=min(ans,buc[tmp]-dep[Rt]+dep[x]-dep[Rt]);}
	}
	for(register int i=h[x];i;i=ver[i]) {
		int y=to[i]; if(y==fa||y==Son) continue;
		upd(y,x,d);
	}
	if(d>0) {if(buc.find(sum[x])==buc.end()) buc[sum[x]]=dep[x]; else buc[sum[x]]=min(buc[sum[x]],dep[x]);}
	else {buc.erase(sum[x]);}
}
inline void dfs2(int x,int fa,int opt) {
	for(register int i=h[x];i;i=ver[i]) {
		int y=to[i]; if(y==fa||y==son[x]) continue;
		dfs2(y,x,0);
	}
	if(son[x]) dfs2(son[x],x,1),Son=son[x];
	Rt=x; upd(x,fa,1); Son=0;
	if(!opt) upd(x,fa,-1); 
}
int main() {
	freopen("P4149_3.in","r",stdin);
	int n=read(); lim=read();
	for(register int i=1;i<n;++i) {
		int x=read()+1,y=read()+1,z=read();
		add(x,y,z); add(y,x,z);
	}
	dfs1(1,-1); dfs2(1,-1,0);
	if(ans==0x3f3f3f3f) printf("-1\n");
	else printf("%d\n",ans);
	return 0;
}
2021/2/20 08:42
加载中...