BZOJ 1827 [Usaco2010 Mar]gather 奶牛大集会(树形DP)
2024-09-02 21:08:48
【题目链接】 http://www.lydsy.com/JudgeOnline/problem.php?id=1827
【题目大意】
给出一棵有点权和边权的树,
请确定一个点,使得每个点到这个点的距离乘上该点乘积的总和最小。
【题解】
定1为根,我们先计算当这个点为1的时候的值,同时记录每个子树的size
之后我们再做一遍dfs,计算出每个点作为中心时候的答案
我们发现当一个点从父节点往子节点移动的时候
对于答案的变化是ans+=(size[1]-2*size[x])*len(fx->x)
所以我们dfs计算,保留最小值即可。
【代码】
#include <cstdio>
#include <algorithm>
#include <vector>
#include <utility>
using namespace std;
const int N=100010;
typedef pair<int,int> P;
typedef long long LL;
vector<P> v[N];
int d[N],size[N],n;
LL ans,ans1;
void dfs(int x,int fx){
for(int i=0;i<v[x].size();i++){
int y=v[x][i].first,z=v[x][i].second;
if(y!=fx){
d[y]=d[x]+z;
ans+=(LL)size[y]*d[y];
dfs(y,x);
size[x]+=size[y];
}
}
}
void dfs2(int x,int fx){
for(int i=0;i<v[x].size();i++){
int y=v[x][i].first,z=v[x][i].second;
if(y!=fx){
ans1+=(LL)(size[1]-2*size[y])*z;
if(ans1<ans)ans=ans1;
dfs2(y,x);
ans1-=(LL)(size[1]-2*size[y])*z;
}
}
}
int main(){
while(~scanf("%d",&n)){
ans=ans1=0;
for(int i=1;i<=n;i++)scanf("%d",&size[i]);
for(int i=1;i<n;i++){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
v[a].push_back(P(b,c));
v[b].push_back(P(a,c));
}dfs(1,-1);ans1=ans;
dfs2(1,-1);
printf("%lld\n",ans);
}return 0;
}
最新文章
- jaee开发起步:tomcat服务器的配置
- title与alt的区别
- Codeforces Round #277.5 (Div. 2) ABCDF
- 前端:IE兼容性的相关方法
- iOS iPad开发之UIPopoverController的使用
- addClass() 和 toggleClass()
- 【Tyvj】1473校门外的树3 线段树/树状数组 <;区间修改+单点访问>;
- javascript中的function
- Xcode连接git@osc
- 用汇编语言研究C语言的全局变量、局部变量、参数、返回值放在哪里
- vue.js学习笔记(一):什么是mvvm框架,vue.js的核心思想
- Java 内存架构
- rpm命令说明
- Oracle数据库中的函数
- TCP/IP 主机路由表获取
- apache 基本vhost配置 【目的及过程】
- C++复习:多态
- UNITY2018 真机开启deepprofiling的操作
- IntelliJ IDEA(Ultimate版本)的下载、安装和WordCount的初步使用(本地模式和集群模式)
- Nginx图片防盗链【实战】
热门文章
- Reachability from the Capital(Codeforces Round #490 (Div. 3)+tarjan有向图缩点)
- Professional Linux Kernel Architecture 笔记 —— 中断处理(Part 2)【转】
- GDB实战
- 网络设备之pci_device_id
- Oracle 内存顾问
- mui 选项卡与header文字同步
- Android内存溢出解决方案总结
- java虚拟机字节码执行引擎
- 比对两个Word文件内容是否一致的C#解决办法
- ubuntu16.04编译安装GPAC