[COCI2014-2015#1] Kamp
CXVI.[COCI2014-2015#1] Kamp
一看题面,突然感觉很弱智,不就是求出以每个点为根到其它所有特殊点的距离之和吗?这不是随随便便换个根就完事了吗?
然后兴冲冲敲出来,一测样例全挂。
后来发现并不是这样的,因为车上可以同时搭载多人,且车最后可以就停在某个地方不回去了。
稍微想想可以发现,最终停着的位置,一定是离起点最远的特殊点;故我们直接使用 multiset
维护一下就可以换根了。求出每个节点离其最远的特殊点的距离后,以它为根的答案就是。
然后,因为车上可以搭载多人,所以实际上上述最短距离就是二倍以当前点和所有特殊点构成的虚树大小。这个可以直接通过求虚树大小的做法(按照dfs序排序再求出两两相邻点间距离)或者干脆直接再来一发换根解决。
时间复杂度。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,m,head[500100],cnt,g[500100];
ll f[500100],h[500100];
bool sp[500100];
struct node{
int to,next,val;
}edge[1001000];
void ae(int u,int v,int w){
edge[cnt].next=head[u],edge[cnt].to=v,edge[cnt].val=w,head[u]=cnt++;
edge[cnt].next=head[v],edge[cnt].to=u,edge[cnt].val=w,head[v]=cnt++;
}
multiset<ll>s[500100];
void dfs1(int x,int fa){
if(sp[x])g[x]++,h[x]=0,s[x].insert(0);
for(int i=head[x],y;i!=-1;i=edge[i].next){
if((y=edge[i].to)==fa)continue;
dfs1(y,x),f[x]+=f[y]+1ll*!!g[y]*edge[i].val,g[x]+=g[y];
h[x]=max(h[x],h[y]+edge[i].val),s[x].insert(h[y]+edge[i].val);
}
}
void dfs2(int x,int fa){
for(int i=head[x],y;i!=-1;i=edge[i].next){
if((y=edge[i].to)==fa)continue;
ll fx=f[x]-f[y]-1ll*!!g[y]*edge[i].val;
int gx=g[x]-g[y];
f[y]+=fx+1ll*!!gx*edge[i].val;
g[y]+=gx;
s[x].erase(s[x].find(h[y]+edge[i].val));
if(!s[x].empty())s[y].insert(*s[x].rbegin()+edge[i].val);
s[x].insert(h[y]+edge[i].val);
h[y]=*s[y].rbegin();
dfs2(y,x);
}
}
int main(){
scanf("%d%d",&n,&m),memset(head,-1,sizeof(head)),memset(h,0xc0,sizeof(h));
for(int i=1,x,y,z;i<n;i++)scanf("%d%d%d",&x,&y,&z),ae(x,y,z);
for(int i=1,x;i<=m;i++)scanf("%d",&x),sp[x]=true;
dfs1(1,0),dfs2(1,0);
// for(int i=1;i<=n;i++)printf("%lld %d %lld\n",f[i],g[i],h[i]);
for(int i=1;i<=n;i++)printf("%lld\n",2*f[i]-h[i]);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?