题意:小C上周末和他可爱的同学小A一起去X湖玩。
X湖景区一共有n个景点,这些景点由n-1条观光道连接着,从每个景点开始都可以通过观光道直接或间接地走到其他所有的景点。小C带着小A从1号景点开始游玩。游览完第一个景点后,先由小C决定下一个游览的景点,他们一起走去那个景点玩。接下来,他们轮流决定他们下一步去哪个景点玩。他们不会选择已经走过的景点,因为重复游览一个景点是无趣的。当他们无法选择下一个景点时,他们就结束旅程。
小C是好动的男孩纸,所以他希望游览的过程尽量长,也就是走过观光道的长度和最大。而小A是文静的女孩纸,她希望游览的过程尽量短。小A和小C都极度聪明,且他们的目光都足够长远,他们做出的决策都是对自己最优的。由于小C在旅游前就仔细研究了X湖景区的地图,他可以在旅行开始前就用自己惊人的数学能力推算出他和小A旅行的路径长度。
小C的梦境是美好的。在他的梦里,他和小A又进行了n-1次旅行,第i次旅行从i+1号点开始,每次也是小C先决定下一个景点,然后小A,然后小C……直到旅行结束。现在小C希望你对于所有n次旅行,求出他和小A旅行的路径长度。

对于100%的数据,N ≤ 300000, c[i] ≤ 1e9

对于60%的数据,N ≤ 3000

思路:对于60分,容易想到枚举根,做N次O(N)的DP,时间复杂度O(n)

对于100分,模拟样例后发现两个直接相连的节点U与V,其DP值只有U与V点时不同,所以考虑当根从U到V时O(1)转移求出新的DP[u]与DP[v]

注意此处不需要保证整个DP数组值都为正确,只要U的值与V的值正确即可

可以想到当U的最值由V转移时,两者交换后V必须从U的另一支转移,所以记录次值

调参大法好

 var f:array[..,..]of int64;
ans:array[..]of int64;
head,vet,next,len,flag:array[..]of longint;
n,tot,i,x,y,z:longint;
oo:int64; procedure add(a,b,c:longint);
begin
inc(tot);
next[tot]:=head[a];
vet[tot]:=b;
len[tot]:=c;
head[a]:=tot;
end; procedure dfs(u:longint);
var e,v,de:longint;
t:int64;
begin
flag[u]:=;
e:=head[u];
de:=;
while e<> do
begin
v:=vet[e];
if flag[v]= then
begin
dfs(v); inc(de);
t:=f[v,]+len[e];
if (t>f[u,])or(f[u,]=) then
begin
f[u,]:=f[u,]; f[u,]:=t;
end
else if (t<=f[u,])and(t>f[u,])or(f[u,]=) then f[u,]:=t; t:=f[v,]+len[e];
if (t<f[u,])or(f[u,]=) then
begin
f[u,]:=f[u,]; f[u,]:=t;
end
else if (t>=f[u,])and(t<f[u,])or(f[u,]=) then f[u,]:=t; end;
e:=next[e];
end; end; procedure change(u:longint);
var e,v:longint;
t,t1,t2,t3,t4:int64;
begin
e:=head[u]; flag[u]:=;
t1:=f[u,]; t2:=f[u,]; t3:=f[u,]; t4:=f[u,]; ans[u]:=f[u,];
while e<> do
begin
v:=vet[e]; if flag[v]= then begin e:=next[e]; continue; end;
if f[v,]+len[e]=t1 then t:=f[u,]+len[e]
else t:=f[u,]+len[e];
if (t<f[v,])or(f[v,]=) then
begin
f[v,]:=f[v,]; f[v,]:=t;
end
else if (t<f[v,])or(f[v,]=) then f[v,]:=t; if f[v,]+len[e]=t3 then begin t:=f[u,]+len[e];end
else t:=f[u,]+len[e]; if (t>f[v,])or(f[v,]=) then
begin
f[v,]:=f[v,]; f[v,]:=t;
end
else if (t>f[v,])or(f[v,]=) then f[v,]:=t;
change(v);
e:=next[e];
end; end; begin
assign(input,'travel.in'); reset(input);
assign(output,'travel.out'); rewrite(output);
oo:=<<;
readln(n); //f[u,]zuida f[u,]cida
//f[u,]zuixiao f[u,]cixiao
for i:= to n- do
begin
readln(x,y,z);
add(x,y,z);
add(y,x,z);
end; dfs();
fillchar(flag,sizeof(flag),);
change();
for i:= to n do writeln(ans[i]);
close(input);
close(output);
end.

【NOIP2016练习】T2 旅行(树形DP,换根)的更多相关文章

  1. bzoj 3743 [Coci2015]Kamp——树形dp+换根

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3743 树形dp+换根. “从根出发又回到根” 减去 “mx ” . 注意dfsx里真的要改那 ...

  2. 树形dp换根,求切断任意边形成的两个子树的直径——hdu6686

    换根dp就是先任取一点为根,预处理出一些信息,然后在第二次dfs过程中进行状态的转移处理 本题难点在于任意割断一条边,求出剩下两棵子树的直径: 设割断的边为(u,v),设down[v]为以v为根的子树 ...

  3. poj3585 Accumulation Degree(树形dp,换根)

    题意: 给你一棵n个顶点的树,有n-1条边,每一条边有一个容量z,表示x点到y点最多能通过z容量的水. 你可以任意选择一个点,然后从这个点倒水,然后水会经过一些边流到叶节点从而流出.问你最多你能倒多少 ...

  4. poj3585 Accumulation Degree[树形DP换根]

    思路其实非常简单,借用一下最大流求法即可...默认以1为根时,$f[x]$表示以$x$为根的子树最大流.转移的话分两种情况,一种由叶子转移,一种由正常孩子转移,判断一下即可.换根的时候由頂向下递推转移 ...

  5. [题解](树形dp/换根)小x游世界树

    2. 小x游世界树 (yggdrasi.pas/c/cpp) [问题描述] 小x得到了一个(不可靠的)小道消息,传说中的神岛阿瓦隆在格陵兰海的某处,据说那里埋藏着亚瑟王的宝藏,这引起了小x的好奇,但当 ...

  6. Acwing-287-积蓄程度(树上DP, 换根)

    链接: https://www.acwing.com/problem/content/289/ 题意: 有一个树形的水系,由 N-1 条河道和 N 个交叉点组成. 我们可以把交叉点看作树中的节点,编号 ...

  7. 2019ICPC沈阳网络赛-D-Fish eating fruit(树上DP, 换根, 点分治)

    链接: https://nanti.jisuanke.com/t/41403 题意: State Z is a underwater kingdom of the Atlantic Ocean. Th ...

  8. bzoj 1131 [POI2008]Sta 树形dp 转移根模板题

    [POI2008]Sta Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1889  Solved: 729[Submit][Status][Discu ...

  9. cf219d 基础换根法

    /*树形dp换根法*/ #include<bits/stdc++.h> using namespace std; #define maxn 200005 ]; int root,n,s,t ...

  10. Codeforces Round #527 (Div. 3) F. Tree with Maximum Cost 【DFS换根 || 树形dp】

    传送门:http://codeforces.com/contest/1092/problem/F F. Tree with Maximum Cost time limit per test 2 sec ...

随机推荐

  1. c3p0,dbcp和proxool

    关于c3p0.dbcp和proxool,之类的比较,配置在网上有很多的文章,我这边就不浪费大家的时间了,主要讲下我用过这三个之后的体会. dbcp:框架以前使用的是dbcp,网上说,有很多BUG,至少 ...

  2. IOS版本判断

    -(void)getIOSVersion { //#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 50000    //此方法和编译器相关 //quanju.iOS ...

  3. 前端应该如何去认识http

    大家应该都知道http是什么吧,肯定会回答不就是浏览器地址那东西吗,有啥好说的,接下来咱们来深入刨析下http这东西. 什么叫http:超文本传输协议(HTTP)是用于传输诸如HTML的超媒体文档的应 ...

  4. bug汇总

    bug 2018年8月23日 bug 1:散点图画不出来. plt.scatter(validation_examples["longitude"], validation_exa ...

  5. Voyager下的Media Manager文件管理与Menu Builder

    Media Manager 默认存储位置在storage/app/public 上传文件,新建文件夹,移动,重命名,删除等等等功能 Menu Builder 创建新的Main菜单 创建一个shop菜单 ...

  6. 【python】python环境搭建

    本文主要用于记录python环境的搭建一些不常用的命令,其他的安装步骤在其他大师可以找到就不详细列出了.(注:以下操作都是在Ubuntu14.04LTS版本) 一.环境查询相关 1.查询当前pytho ...

  7. Linux菜鸟起飞之路【十】进程管理

    一.基本概念 进程:程序的一次动态执行 守护进程:在后台运行并提供系统服务的进程 僵尸进程:完成了生命周期但却依然留在进程表中的进程,我们称之为 “僵尸进程” 父进程:指已创建一个或多个子进程的进程. ...

  8. 常用的windows小工具指令和如何打开自定义的程序

    windows可以通过 开始->运行->输入程序名 或 windows键+R键 两种方式来启动windows中自带的程序或手动安装的程序.下面介绍一些常用的windows工具的指令和如何打 ...

  9. LeetCode(190) Reverse Bits

    题目 Reverse bits of a given 32 bits unsigned integer. For example, given input 43261596 (represented ...

  10. zigbee 中 OSAL 事件传递机制和消息传递机制

    一.概述 OSAL (Operating System Abstraction Layer) ,翻译为"操作系统抽象层". OSAL 就是一种支持多任务运行的系统资源分配机制.OS ...