社区讨论
S组T4正解
学术版参与者 7已保存回复 8
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 8 条
- 当前快照
- 1 份
- 快照标识符
- @lo7o34wo
- 此快照首次捕获于
- 2023/10/27 04:59 2 年前
- 此快照最后确认于
- 2023/10/27 04:59 2 年前
本来看着 T4 很好做的样子,打了一个树剖加树形,拿 部分分,但到最后也没有调出来。听说 T4 正解也是这个,想请教一下树形的空间和时间怎么优化或者调一下这个代码。
CPP#include <bits/stdc++.h>
using namespace std;
int n,q,k;
const int N=1e4+5,M=4e5+5;
int a[N];
int u,v;
int head[N],ecnt;
struct edge{
int v,nxt;
}e[M];
void add(int u,int v){
e[ecnt].v=v;
e[ecnt].nxt=head[u];
head[u]=ecnt++;
}
int dep[N],fa[N],ch[N],siz[N],ind[N],top[N];
void dfs(int u,int f,int d){
int max_ch=0;
dep[u]=d;
fa[u]=f;
siz[u]=1;
for(int i=head[u];i+1;i=e[i].nxt){
int v=e[i].v;
if(v==fa[u]) continue;
dfs(v,u,d+1);
siz[u]+=siz[v];
if(siz[v]>max_ch){
max_ch=siz[v];
ch[u]=v;
}
}
}
int windex;
void dfs2(int u,int tp){
ind[u]=++windex;
top[u]=tp;
if(ch[u]==0) return ;
//cout<<u<<' '<<ch[u]<<endl;
dfs2(ch[u],tp);
for(int i=head[u];i+1;i=e[i].nxt){
int v=e[i].v;
if(v==fa[u]||v==ch[u]) continue;
dfs2(v,v);
}
}
int f[N][N];
void dp(int u){
f[u][u]=a[u];
for(int i=fa[u],q=1;i+1&&q<=k+1;i=fa[i],q++){
for(int j=i;j+1;j=fa[j]){
f[j][u]=min(f[j][u],f[j][i]+a[u]);
//cout<<j<<' '<<u<<' '<<f[j][u]<<endl;
}
}
for(int i=head[u];i+1;i=e[i].nxt){
int v=e[i].v;
if(v!=fa[u]) dp(v);
}
}
int lca(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
x=fa[top[x]];
}
if(dep[x]<dep[y]) return x;
return y;
}
int main(){
freopen("transmit.in","r",stdin);
freopen("transmit.out","w",stdout);
cin>>n>>q>>k;
memset(head,-1,sizeof(head));
memset(f,0x3f,sizeof(f));
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n-1;i++){
cin>>u>>v;
add(u,v);
add(v,u);
}
dfs(1,-1,1);
dfs2(1,1);
dp(1);
int x,y;
/*cout<<lca(4,7)<<endl;
cout<<f[1][5]<<endl;*/
while(q--){
cin>>x>>y;
cout<<f[lca(x,y)][x]+f[lca(x,y)][y]-a[lca(x,y)]<<endl;
}
return 0;
}
回复
共 8 条回复,欢迎继续交流。
正在加载回复...