求助虚树TLE
查看原帖
求助虚树TLE
158400
晴空一鹤楼主2023/8/22 16:44

按理来说这题应该不需要卡常?但我写的虚树跑的飞慢,求指出哪里写假了。

#include<bits/stdc++.h>
using namespace std;
#define nx v[u[x][i]]
#define int long long
int fa[20][250005],dep[250005],st[20][250005],a[500005],v[250005],w[250005],n,m,x,y,dfn[250005],cnt;//fa->the number of which edge is one's dad
vector<int>u[250005],uu[250005],uuu[250005];
bool r[250005],le[250005];
void inline getfa(int x,int y,int ww,int d){
	cnt++;
	dfn[x]=cnt;
	r[x]=1;	
	fa[0][x]=y;if(x!=1)st[0][x]=ww;
	dep[x]=d;
	for(int i=1;i<=19;i++)
	if(fa[i-1][fa[i-1][x]]!=0)
	fa[i][x]=fa[i-1][fa[i-1][x]];
	for(int i=1;i<=19;i++)
	st[i][x]=min(st[i-1][x],st[i-1][fa[i-1][x]]);
	for(int i=0;i<u[x].size();i++)
	if(!r[nx])getfa(nx,x,w[u[x][i]],d+1);
    r[x]=0;
}
int inline lca(int x,int y){
	//cout<<"h";
	int i=0,ui;
	if(dep[x]<dep[y])
	swap(x,y);
	ui=dep[x]-dep[y];
	while(ui){
		if(ui&1)x=fa[i][x];
		ui>>=1;
		i++;
	}
	i=19;
	while(i+1){
		if(fa[i][x]!=fa[i][y])x=fa[i][x],y=fa[i][y];
		i--;
	}
	if(x==y)return x;
	return fa[0][x];
}
int inline mi(int x,int y){
	//cout<<"a";
	int i=0,ans=1000000000000000,uv=dep[x]-dep[y];
	while(uv){
		if(uv&1){
			ans=min(ans,st[i][x]);
			x=fa[i][x];
		}
		i++;
		uv>>=1;
	}
	return ans;
}
int inline dp(int x){
//	cout<<"l";
	r[x]=1;int ans=0,no=0;
	for(int i=0;i<uu[x].size();i++)
	if(!r[uu[x][i]])if(le[uu[x][i]])ans+=uuu[x][i],no++;else ans+=min(uuu[x][i],dp(uu[x][i])),no++;	
	r[x]=0;
	if(no==0)return 1000000000000000;
	return ans;
}
bool inline cmp(int x,int y){
	return dfn[x]<dfn[y];
}
signed main(){
	cin>>n;
	for(int i=1;i<n;i++){
	cin>>x>>v[i*2-1]>>w[i*2-1];
	u[x].push_back(i*2-1);
	w[i<<1]=w[i*2-1];
	v[i<<1]=x;
	u[v[i*2-1]].push_back(i<<1);}
	fa[0][1]=1;	for(int i=0;i<=19;i++)st[i][1]=1000000000000000;
	getfa(1,1,0,1);
	//for(int i=0;i<=19;i++)
	//for(int j=1;j<=n;j++)
	//cout<<i<<" "<<j<<" "<<fa[i][j]<<" "<<st[i][j]<<endl;

	cin>>m;
	for(int i=1;i<=m;i++){
		cin>>x;
		for(int i=1;i<=x;i++){
			cin>>a[i];le[a[i]]=1;
			if(i>1)
			a[x+i-1]=lca(a[i],a[i-1]);
		}
		a[x+x]=1;
		sort(a+1,a+x+x+1,cmp);
		for(int i=2;i<=x*2;i++){
		    if(a[i]!=a[i-1]){
			y=lca(a[i],a[i-1]);
			uu[y].push_back(a[i]);
			uuu[y].push_back(mi(a[i],y));
			uu[a[i]].push_back(y);
			uuu[a[i]].push_back(mi(a[i],y));
		}}
		cout<<dp(1)<<endl;
	//	for(int i=1;i<=2*x;i++)cout<<a[i]<<"hhh";cout<<endl;
		for(int i=1;i<=x*2;i++)
		uu[a[i]].clear(),uuu[a[i]].clear(),le[a[i]]=0;
	}
}
2023/8/22 16:44
加载中...