洛谷 P1131 [ZJOI2007]时态同步 树形DP
2024-09-02 13:06:47
题目描述
分析
我们从根节点开始搜索,搜索到叶子节点,回溯的时候进行维护
先维护节点的所有子节点到该节点最大边权(边权为叶子节点到同时到达它所需要时间)
然后维护答案,答案为最大边权减去所有到子节点的边权。
然后维护父节点的边权,父节点边权为该节点子节点的 最大边权+父节点到该节点的时间。
然后就回溯,重复操作,到根节点为止。
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e6+5;
typedef long long ll;
struct asd{
int from,to,next;
ll val;
}b[maxn];
int head[maxn],tot=1;
void ad(int aa,int bb,ll cc){
b[tot].from=aa;
b[tot].to=bb;
b[tot].next=head[aa];
b[tot].val=cc;
head[aa]=tot++;
}
ll f[maxn];
ll sum[maxn],ans[maxn];
ll siz[maxn];
void dfs(int now,int fa){
for(int i=head[now];i!=-1;i=b[i].next){
int u=b[i].to;
if(u==fa) continue;
dfs(u,now);
sum[now]=max(sum[now],b[i].val+sum[u]);
}
}//第一遍dfs求出修改后m节点到叶子节点的权值之和
void dfs2(int now,int fa){
for(int i=head[now];i!=-1;i=b[i].next){
int u=b[i].to;
if(u==fa) continue;
f[now]+=sum[now]-sum[u]-b[i].val;
dfs2(u,now);
f[now]+=f[u];
}
}//第二遍dfs求出修改以m节点为根的子树所需要的最小花费
int main(){
memset(head,-1,sizeof(head));
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<n;i++){
int aa,bb;
ll cc;
scanf("%d%d%lld",&aa,&bb,&cc);
ad(aa,bb,cc);
ad(bb,aa,cc);
}
dfs(m,0);
dfs2(m,0);
printf("%lld\n",f[m]);
return 0;
}
最新文章
- Fast RCNN 训练自己的数据集(3训练和检测)
- gulp使用笔记
- [LeetCode]题解(python):052-N-Queens II
- LINUX防火墙firewall、iptables
- Selenium 初见
- 【转】Android开发工具--android-studio-bundle-141.2288178
- Codeforces Round #261 (Div. 2)——Pashmak and Buses
- OC之KVC,KVO
- 生成订单:三个表(Products,Orders,OrderItem)
- ImageLoader配置(凝视)
- Python 基础【一】
- SQL SERVER数据库附加是只读的解决方法
- ResultHandler的用法
- Http协议和Https协议的安全性问题
- shell文件查找和压缩命令
- 20155237 第十一周java课堂程序
- Android模拟器内安装应用
- J2EE 13种技术规范
- (剑指Offer)面试题3:二维数组中的查找
- 003——数组(三)count()reset()end()prev()next()current()