Luogu P3647 [APIO2014]连珠线
题目
换根dp。
显然对于给定的一棵有根树,蓝线都不能拐弯。
设\(f_{u,0}\)表示\(u\)不是蓝线中点时子树内的答案,\(f_{u,1}\)表示\(u\)是蓝线中点时子树内的答案。(以\(1\)为根的情况下)
那么显然有\(f_{u,0}=\sum\limits_{v\in son_u}\max(f_{v,0},f_{v,1}+d_v)\)。
(\(son_u\)表示\(u\)的儿子集合,\(d_u\)表示\((u,fa_u)\)的长度)
但是\(f_{u,1}\)如何求?
我们这样考虑:穿过\(u\)的蓝线就一条,我们枚举这条蓝线到它的哪个儿子,这个儿子的单独算,其它的儿子的答案则和上面一样(这一部分可以直接蒯下来而不必另算)。
\(f_{u,1}=f_{u,0}+\max\limits_{v\in son_u}(f_{v,0}+d_v-\max(f_{v,0},f_{v,1}+d_v))\)。
然后我们可以\(O(n^2)\)做了对吧。
再设\(g_{u,0,v}\)表示和上面一样的意义,并且不考虑\(u\)的孩子\(v\)情况下的答案。
显然有\(g_{u,0,v}=f_{u,0}-\max(f_{v,0},f_{v,1}+d_v)\)。
\(g_{u,1,t}=g_{u,0,t}+\max\limits_{v\in son_u\wedge v\neq t}(f_{v,0}+d_v-\max(f_{v,0},f_{v,1}+d_v))\)。
这个我们可以在每次计算\(f_{u,1}\)时处理出\((f_{v,0}+d_v-\max(f_{v,0},f_{v,1}+d_v))\)的最大值和次大值来计算。
然后开始换根。
还是dfs,对于\(u\)以及\(v\in son_u\),我们这样计算:
把\(g_{u,?,v}\)赋给\(f_{u,?}\),然后把父亲的\(f\)以及\(d_u\)合并到\(u\)来,再统计答案。
这样我们可以保证在\((1,u)\)这条链上,每个点都只计算了这条链以外儿子的子树的答案以及连接它自己和它的父亲的答案,即\(u\)的\(v\)以外子树的答案。
具体的看看代码能够很轻松地理解。
#include<bits/stdc++.h>
#define pi pair<int,int>
#define pb push_back
using namespace std;
const int N=200003,inf=1e9;
vector<pi>E[N];int f[N][2],fa[N],d[N],ans;vector<int>son[N],g[N][2],mx[N];
int read(){int x=0,c=getchar();while(!isdigit(c))c=getchar();while(isdigit(c))x=x*10+c-48,c=getchar();return x;}
int max(int a,int b){return a>b? a:b;}
int min(int a,int b){return a<b? a:b;}
void dfs(int u)
{
int mx1=-inf,mx2=-inf,x;
for(auto [v,w]:E[u])
{
if(v==fa[u]) continue;
d[v]=w,fa[v]=u,son[u].pb(v),dfs(v),f[u][0]+=max(f[v][0],f[v][1]+w),x=f[v][0]+w-max(f[v][0],f[v][1]+w);
if(x>mx1) mx2=mx1,mx1=x; else if(x>mx2) mx2=x;
}
f[u][1]=f[u][0]+mx1;
for(auto [v,w]:E[u])
{
if(v==fa[u]) continue;
g[u][0].pb(f[u][0]-max(f[v][0],f[v][1]+w)),x=f[v][0]+w-max(f[v][0],f[v][1]+w);
x==mx1? (g[u][1].pb(g[u][0].back()+mx2),mx[u].pb(mx2)):(g[u][1].pb(g[u][0].back()+mx1),mx[u].pb(mx1));
}
}
void dp(int u)
{
for(int i=0;i<son[u].size();++i)
{
f[u][0]=g[u][0][i],f[u][1]=g[u][1][i];
if(fa[u]) f[u][0]+=max(f[fa[u]][0],f[fa[u]][1]+d[u]),f[u][1]=f[u][0]+max(mx[u][i],f[fa[u]][0]+d[u]-max(f[fa[u]][0],f[fa[u]][1]+d[u]));
ans=max(ans,f[son[u][i]][0]+max(f[u][0],f[u][1]+d[son[u][i]])),dp(son[u][i]);
}
}
int main()
{
int i,n,u,v,w;n=read();
for(i=1;i<n;++i) u=read(),v=read(),w=read(),E[u].pb(pi(v,w)),E[v].pb(pi(u,w));
dfs(1),dp(1),cout<<ans;
}
Luogu P3647 [APIO2014]连珠线的更多相关文章
- [换根DP]luogu P3647 [APIO2014]连珠线
题面 https://www.luogu.com.cn/problem/P3647 不重复地取树中相邻的两条边,每次得分为两条边权和,问最大得分 分析 容易想到状态 f[i][0/1] 分别表示 i ...
- 洛谷$P3647\ [APIO2014]$连珠线 换根$dp$
正解:换根$dp$ 解题报告: 传送门! 谁能想到$9102$年了$gql$居然还没写过换根$dp$呢,,,$/kel$ 考虑固定了从哪个点开始之后,以这个点作为根,蓝线只可能是直上直下的,形如&qu ...
- 洛谷 P3647 [APIO2014]连珠线(换根 dp)
题面传送门 题意: 桌子上有 \(1\) 个珠子,你要进行 \(n-1\) 次操作,每次操作有以下两种类型: 拿出一个新珠子,并选择一个桌子上的珠子,在它们之间连一条红线 选择两个由红线相连的珠子 \ ...
- 并不对劲的bzoj3677:p3647:[APIO2014]连珠线
题目大意 有一种生成\(n\)个点的树的方法为: 一开始有一个点,\(n-1\)次操作,每次可以有两种操作:1.选一个点,用一条红边将它与新点连接:2.将新点放在一条红边上,新点与这条红边两端点直接的 ...
- 【BZOJ3677】[Apio2014]连珠线 换根DP
[BZOJ3677][Apio2014]连珠线 Description 在列奥纳多·达·芬奇时期,有一个流行的童年游戏,叫做“连珠线”.不出所料,玩这个游戏只需要珠子和线,珠子从1到礼编号,线分为红色 ...
- [Bzoj3677][Apio2014]连珠线(树形dp)
3677: [Apio2014]连珠线 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 434 Solved: 270[Submit][Status] ...
- 【LG3647】[APIO2014]连珠线
[LG3647][APIO2014]连珠线 题面 洛谷 题解 首先考虑一下蓝线连起来的情况,一定是儿子-父亲-另一个儿子或者是儿子-父亲-父亲的父亲. 而因为一开始只有一个点在当前局面上,将一条红边变 ...
- 题解 [APIO2014]连珠线
题解 [APIO2014]连珠线 题面 解析 首先这连成的是一棵树啊. 并且\(yy\)一下,如果钦定一个根, 那么这上面的蓝线都是爸爸->儿子->孙子这样的,因为像下图这样的构造不出来: ...
- bzoj3677: [Apio2014]连珠线
Description 在列奥纳多·达·芬奇时期,有一个流行的童年游戏,叫做“连珠线”.不出所料,玩这个游戏只需要珠子和线,珠子从1到礼编号,线分为红色和蓝色.游戏 开始时,只有1个珠子,而接下来新的 ...
随机推荐
- 51 Nod 1089 最长回文子串(Manacher算法)
1089 最长回文子串 V2(Manacher算法) 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 回文串是指aba.abba.cccbccc.aaa ...
- cat:连接文件并打印输出到标准输出设备
是 concatenate(连接.连续)的简写.cat 命令可以用来显示文本文件的内容,也可以把几个文件内容附加到另一个文件中,即连接合并文件. cat 命令的基本格式如下: [root@localh ...
- Jmeter(三) 从上传图片来入门Jmeter
用Jmeter上传用户头像到人人网 先用抓包工具Fiddler把上传操作的报文抓取下来 开启Jmeter,在测试计划中创建一个线程组,取名为“图片上传” 再在线程组中创建一个HTTP请求 在请求报文中 ...
- 关于多个py文件生成一个可运行exe文件(用pyinstaller)
首先下载Pyinstaller,在cmd命令下执行:pip installer Pyinstaller,不需要关心安装在哪 然后把所有相关的py文件都放在一个目录下 在那个目录下执行cmd命令:pyi ...
- node.js渲染页面
1 在软件中找到nodejs并安装(强调,安装时选默认位置) 2 复制yuedu文件夹到本地 3 在yuedu文件夹中按shift 点击右键 4 输入命令 npm install 5 安装成功后,输入 ...
- MQTT QOS含义
特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...
- 使用Desktop App Converter打包桌面应用程序
打包具有安装程序 (.msi) 的应用程序 DesktopAppConverter.exe -Installer C:\Installer\MyAppSetup.msi -Destination C: ...
- Spark学习(二)——RDD的设计与运行原理
Spark的核心是建立在统一的抽象RDD之上,使得Spark的各个组件可以无缝进行集成,在同一个应用程序中完成大数据计算任务.RDD的设计理念源自AMP实验室发表的论文<Resilient Di ...
- Ruby Programming学习笔记
#将ARGV[0]转换成正则表达式类型 pattern= Regexp.new(ARGV[0]) #Devise gem包 Devise是Ruby中使用最广泛的身份验证gem包之一.Devise为我们 ...
- 过滤器修改response
过滤器通过doFilter方法的第二个参数ServletResponse将输出发送给客户,但servletResponse参数没有为过滤器提供servlet或jsp页面的访问:执行doFilter方法 ...