比赛 CSP2022提高组 评测结果 AWAWWAAAAWWAATTTTTTWTTTTT
题目名称 数据传输 最终得分 32
用户昵称 op_组撒头屯 运行时间 37.244 s
代码语言 C++ 内存使用 0.00 MiB
提交时间 2022-10-30 11:28:10
显示代码纯文本
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=200000+5;
struct sdf{
	int to,next;
}eg[2*N];
int head[N],ne=0;
int n,q,k,lgn;
ll w[N],s[N];
void add(int x,int y){
	eg[++ne]={y,head[x]};
	head[x]=ne;return ; 
}
int d[N],anc[N][23];
int fat[N];
void dfs(int pt,int fa){
	anc[pt][0]=fa;d[pt]=d[fa]+1;
	s[pt]=s[fa]+w[pt];fat[pt]=fa;
	for (int i=head[pt];i!=0;i=eg[i].next){
		int v=eg[i].to;
		if (v==fa)continue;
		dfs(v,pt);
	}
}
ll lca(int x,int y){
	if (d[x]<d[y])swap(x,y);
	for (int i=lgn;i>=0;i--){
		if (anc[x][i]&&d[anc[x][i]]>=d[y]){
			x=anc[x][i];
		}
		if (x==y)return x;
	}
	for (int i=lgn;i>=0;i--){
		if (anc[x][i]!=anc[y][i]){
			x=anc[x][i];
			y=anc[y][i];
		}
	}
	return anc[x][0];
}
void solve1(){
	while(q--){
		int x,y;scanf("%d%d",&x,&y);
		int l=lca(x,y);
		printf("%lld\n",s[x]+s[y]-2*s[l]+w[l]);
	}
	return ;
}
ll f[N+2];
int lf[5],cnt=0;
void calc(int x,int y){
	if (x==y)return ;
	int fa=fat[x];
	f[fa]=min(f[fa],f[x]+w[x]);
	f[fat[fa]]=min(f[fat[fa]],f[x]+w[x]);
	if (fa==y)lf[++cnt]=x;
	calc(fa,y);
	return ;
}
void solve2(){
	while(q--){
		int x,y;scanf("%d%d",&x,&y);
		int l=lca(x,y);
		cnt=0;lf[1]=lf[2]=0;
		memset(f,0x3f,sizeof(f));
		f[x]=0;ll tmp;
		calc(x,l);tmp=f[l];f[l]=f[n+1];
		f[y]=0;
		calc(y,l);
		int s=lf[1],t=lf[2];
		printf("%lld\n",min(f[s]+w[s]+f[t]+w[t],tmp+f[l]+w[l]));
	}
}
int main(){
	freopen ("csp2022_transmit.in","r",stdin);
	freopen ("csp2022_transmit.out","w",stdout);
	scanf("%d%d%d",&n,&q,&k);lgn=1.0*log(n)/log(2.0);
	for (int i=1;i<=n;i++)scanf("%lld",&w[i]);
	for (int i=1;i<n;i++){
		int x,y;scanf("%d%d",&x,&y);
		add(x,y);add(y,x);
	}
	dfs(1,0);
	for (int i=1;i<=lgn;i++){
		for (int j=1;j<=n;j++)anc[j][i]=anc[anc[j][i-1]][i-1];	
	}
	if (k==1){
		solve1();return 0;
	}
	if (k==2||k==3){
		solve2();return 0;
	}
}