第一个点没过(就是样例2),求条
查看原帖
第一个点没过(就是样例2),求条
615438
jpjpjpjp楼主2024/9/6 20:22

rt,马蜂有亿点点丑

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=7e5+3;
struct edge{
	int v,w,nxt;
}eg[maxn<<1];
int head[maxn],tot=0;
int dp[maxn][2],d[maxn],cm[maxn];//1最后进该子树,0不是最后进该子树 
int cnt[maxn],k[maxn],n,m,f[maxn][3];
int g[3],cm2[maxn];
void add(int u,int v,int w){
	eg[++tot]={v,w,head[u]};
	head[u]=tot;
}
void dfs(int u,int fa){
//	cout<<"u="<<u<<" fa="<<fa<<endl; 
	if(k[u]==1)cnt[u]=1;
	for(int i=head[u];i;i=eg[i].nxt){
		int v=eg[i].v,w=eg[i].w;
		if(v==fa)continue;
		dfs(v,u);
		if(cnt[v])dp[u][0]+=dp[v][0]+w*2;
		cnt[u]+=cnt[v];
	}
	//dp[u][1]最小,d[u]次小 
	int d1=1e17+3,d2=1e17+3; 
	for(int i=head[u];i;i=eg[i].nxt){
		int v=eg[i].v,w=eg[i].w;
		if(v==fa)continue;
		if(cnt[v]){
			if(dp[u][0]-w-dp[v][0]+dp[v][1]<d1){
				d2=d1;
				d1=dp[u][0]-w-dp[v][0]+dp[v][1];
				cm[u]=v;
			}
			else if(dp[u][0]-w-dp[v][0]+dp[v][1]<d2)
				d2=dp[u][0]-w-dp[v][0]+dp[v][1];
//			if(u==4)cout<<"v="<<v<<" dp0="<<dp[v][0]<<" dp1="<<dp[v][1]<<" w="<<w<<" dpu0="<<dp[u][0]<<endl; 
//			if(dp[u][1])dp[u][1]=min(dp[u][1],dp[u][0]-w-dp[v][0]+dp[v][1]);
//			else dp[u][1]=dp[u][0]-w-dp[v][0]+dp[v][1];
		}
	}
	if(d1!=1e17+3)dp[u][1]=d1;
	d[u]=d2;
//	cout<<"u="<<u<<endl;
//	cout<<dp[u][0]<<" "<<dp[u][1]<<endl;
}
void dfs2(int u,int fa){
	for(int i=head[u];i;i=eg[i].nxt){
		int v=eg[i].v,w=eg[i].w;
		if(v==fa)continue;
		if(v!=cm2[u]){
			g[0]=f[u][0]-dp[v][0]+dp[v][1],g[1]=d[v]+f[u][0],g[2]=f[u][1]-(cnt[v]?w:-w);
//			cout<<"v="<<v<<endl;
//			cout<<"g0="<<g[0]<<" g1="<<g[1]<<" g2="<<g[2]<<endl;
			sort(g,g+3);
			f[v][1]=g[0];f[v][2]=g[1];f[v][0]=f[u][0];
			if(g[0]==g[1])cm2[v]=-1;
			else if(f[v][1]==f[u][0]-dp[v][0]+dp[v][1])cm2[v]=cm[v];
			else if(f[v][1]==f[u][1]-w)cm2[v]=u;
		}
		else {
			g[0]=f[u][0]-dp[v][0]+dp[v][1],g[1]=d[v]+f[u][0]-dp[v][0],g[2]=f[u][2]-(cnt[v]?w:-w);
			sort(g,g+3);
//			cout<<"v="<<v<<endl;
//			cout<<"g0="<<g[0]<<" g1="<<g[1]<<" g2="<<g[2]<<endl;
			f[v][1]=g[0];f[v][2]=g[1];f[v][0]=f[u][0];
			if(g[0]==g[1])cm2[v]=-1;
			else if(f[v][1]==f[u][0]-dp[v][0]+dp[v][1]&&g[0]!=g[1])cm2[v]=cm[v];
			else if(f[v][1]==f[u][2]-w&&g[0]!=g[1])cm2[v]=u;
		}
		dfs2(v,u);
	}
}
signed main(){
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<n;i++){
		int u,v,w;scanf("%lld%lld%lld",&u,&v,&w);
		add(u,v,w);add(v,u,w);
	}
	for(int i=1;i<=m;i++){
		int x;scanf("%lld",&x);k[x]=1;
	}
	dfs(1,0);
	f[1][0]=dp[1][0],f[1][1]=dp[1][1],f[1][2]=d[1];
	cm2[1]=cm[1];
//	for(int i=1;i<=n;i++)cout<<"i="<<i<<" dp0="<<dp[i][0]<<" dp1="<<dp[i][1]<<" d="<<d[i]<<" cm="<<cm[i]<<endl;
	dfs2(1,0);
//	for(int i=1;i<=n;i++)cout<<"i="<<i<<" f0="<<f[i][0]<<" f1="<<f[i][1]<<" f2="<<f[i][2]<<" cm2="<<cm2[i]<<endl;
	for(int i=1;i<=n;i++)cout<<f[i][1]<<'\n';
	return 0;
}
/*
7 3
1 2 4
1 3 1
2 5 1
2 4 2
4 7 3
4 6 2
3
5
7
*/
2024/9/6 20:22
加载中...