题目链接:戳我

换根DP

由于蒟蒻不会做这个题,所以参考了大佬。

本来想的是有三种情况,一种是该节点不作为两个蓝线的中点(我们称这种不是关键节点),一种是该节点作为关键点、连两个子节点,一种是作为关键节点、一个连子节点一个连父亲节点。

然后有一个不换根的树形DP,但是正确性emmm尚待商榷。

对于一个这样的图——

我们可以发现,如果想要连起来的话,我们需要不止一个根节点,而这与题目中提到的每次加入一个节点不符。

所以我们考虑换根。这样的话我们发现,就只有两种情况了——一种是该节点不作为关键节点,一种是作为关键节点、连父亲和儿子。

设\(f[i][0]\)表示对于以i为根的子树,该节点不作为关键节点的最大收益。

设\(f[i][1]\)表示对于以i为根的子树,该节点作为关键节点、连父节点和子节点的最大收益。

\(f[i][0]=max(f[i][0],f[i][1]+edge[i].dis)\)

\(f[i][1]=max(f[i][1],f[i][0]-max(dp[v][0],dp[v][1]+dis)+dis+dp[v][0])\)

之后维护一个\((f[i][0]-max(dp[v][0],dp[v][1]+dis)+dis+dp[v][0])\)的前后缀即可。

具体看代码qwqwq

代码如下:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<algorithm>
#define MAXN 200010
#define INF 0x3f3f3f3f
using namespace std;
int n,t,ans;
int head[MAXN],f[MAXN][2];
vector<int>son[MAXN],pef[MAXN],suf[MAXN],dis[MAXN];
struct Edge{int nxt,to,dis;}edge[MAXN<<1];
inline void add(int from,int to,int dis)
{
edge[++t].nxt=head[from],edge[t].to=to,edge[t].dis=dis,head[from]=t;
edge[++t].nxt=head[to],edge[t].to=from,edge[t].dis=dis,head[to]=t;
}
inline int dfs1(int x,int pre)
{
f[x][0]=0,f[x][1]=-INF;
for(int i=head[x];i;i=edge[i].nxt)
{
int v=edge[i].to;
if(v==pre) continue;
son[x].push_back(v),dis[x].push_back(edge[i].dis);
}
for(int i=0;i<son[x].size();i++)
{
int v=son[x][i],dist=dis[x][i];
dfs1(v,x);
f[x][0]+=max(f[v][0],f[v][1]+dist);
pef[x].push_back(f[v][0]-max(f[v][0],f[v][1]+dist)+dist);
suf[x].push_back(f[v][0]-max(f[v][0],f[v][1]+dist)+dist);
}
for(int i=0;i<son[x].size();i++) f[x][1]=max(f[x][1],f[x][0]+pef[x][i]);
for(int i=1;i<son[x].size();i++) pef[x][i]=max(pef[x][i],pef[x][i-1]);
for(int i=son[x].size()-2;i>=0;i--) suf[x][i]=max(suf[x][i],suf[x][i+1]);
}
inline void dfs2(int x,int f0,int f1,int dist)
{
f[x][0]+=max(f0,f1+dist);
f[x][1]+=max(f0,f1+dist);
f[x][1]=max(f[x][1],f[x][0]+f0-max(f0,f1+dist)+dist);
ans=max(ans,f[x][0]);
for(int i=0;i<son[x].size();i++)
{
int v=son[x][i];
int cur0=f[x][0]-max(f[v][0],f[v][1]+dis[x][i]);
int delta=f0-max(f0,f1+dist)+dist;
if(i!=0) delta=max(delta,pef[x][i-1]);
if(i!=son[x].size()-1) delta=max(delta,suf[x][i+1]);
dfs2(v,cur0,cur0+delta,dis[x][i]);
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
scanf("%d",&n);
for(int i=1;i<n;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
}
dfs1(1,0);
dfs2(1,0,-INF,-INF);
printf("%d\n",ans);
return 0;
}

APIO2014 连珠线的更多相关文章

  1. 【BZOJ3677】[Apio2014]连珠线 换根DP

    [BZOJ3677][Apio2014]连珠线 Description 在列奥纳多·达·芬奇时期,有一个流行的童年游戏,叫做“连珠线”.不出所料,玩这个游戏只需要珠子和线,珠子从1到礼编号,线分为红色 ...

  2. [Bzoj3677][Apio2014]连珠线(树形dp)

    3677: [Apio2014]连珠线 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 434  Solved: 270[Submit][Status] ...

  3. 【LG3647】[APIO2014]连珠线

    [LG3647][APIO2014]连珠线 题面 洛谷 题解 首先考虑一下蓝线连起来的情况,一定是儿子-父亲-另一个儿子或者是儿子-父亲-父亲的父亲. 而因为一开始只有一个点在当前局面上,将一条红边变 ...

  4. 题解 [APIO2014]连珠线

    题解 [APIO2014]连珠线 题面 解析 首先这连成的是一棵树啊. 并且\(yy\)一下,如果钦定一个根, 那么这上面的蓝线都是爸爸->儿子->孙子这样的,因为像下图这样的构造不出来: ...

  5. bzoj3677: [Apio2014]连珠线

    Description 在列奥纳多·达·芬奇时期,有一个流行的童年游戏,叫做“连珠线”.不出所料,玩这个游戏只需要珠子和线,珠子从1到礼编号,线分为红色和蓝色.游戏 开始时,只有1个珠子,而接下来新的 ...

  6. bzoj 3677: [Apio2014]连珠线【树形dp】

    参考:http://www.cnblogs.com/mmlz/p/4456547.html 枚举根,然后做树形dp,设f[i][1]为i是蓝线中点(蓝线一定是父子孙三代),f[i][0]为不是,转移很 ...

  7. Luogu P3647 [APIO2014]连珠线

    题目 换根dp. 显然对于给定的一棵有根树,蓝线都不能拐弯. 设\(f_{u,0}\)表示\(u\)不是蓝线中点时子树内的答案,\(f_{u,1}\)表示\(u\)是蓝线中点时子树内的答案.(以\(1 ...

  8. 洛谷$P3647\ [APIO2014]$连珠线 换根$dp$

    正解:换根$dp$ 解题报告: 传送门! 谁能想到$9102$年了$gql$居然还没写过换根$dp$呢,,,$/kel$ 考虑固定了从哪个点开始之后,以这个点作为根,蓝线只可能是直上直下的,形如&qu ...

  9. 洛谷 P3647 [APIO2014]连珠线(换根 dp)

    题面传送门 题意: 桌子上有 \(1\) 个珠子,你要进行 \(n-1\) 次操作,每次操作有以下两种类型: 拿出一个新珠子,并选择一个桌子上的珠子,在它们之间连一条红线 选择两个由红线相连的珠子 \ ...

随机推荐

  1. Qt(自适应窗口)

    关于窗口布局: 默认控件的大小为最小尺寸: 如果此时右键设置布局时,窗口大小会自动缩放对应大小,不利于调整. 建议窗口控件设置好最小尺寸,便于窗口布局时,控件不会变形,例如: 改变minimumsiz ...

  2. Git(二):常用 Git 命令清单

    转: http://www.ruanyifeng.com/blog/2015/12/git-cheat-sheet.html 我每天使用 Git ,但是很多命令记不住. 一般来说,日常使用只要记住下图 ...

  3. avalon最佳实践

    最近从angular的QQ群与新浪微博拉了许多人来用我的avalon,成为第一批登上方舟,脱离DOM苦海的人.短短三个月内,5群的朋友也搞出几个切实实行的案例了.为应对粉丝们高益高涨的热情,遂放出此文 ...

  4. Linux实战教学笔记41:企业级SVN版本管理与大型代码上线方案

    第1章 SVN服务实战应用指南 1.1 SVN介绍 1.1.1 什么是SVN(Subversion)? Svn(subversion)是近年来崛起的非常优秀的版本管理工具,与CVS管理工具一样,SVN ...

  5. jmeter压力测试的简单实例+badboy脚本录制

    JMeter的安装:在网上下载,在下载后的zip解压后,在bin目录下找到JMeter.bat文件,双击就可以运行JMeter. http://jmeter.apache.org/ 在使用jmeter ...

  6. Xcode8 问题

    ios10 定位问题,在plist中手动添加NSCameraUsageDescription http://www.cocoachina.com/bbs/read.php?tid-1685721.ht ...

  7. faster-rcnn目录介绍

    data 用来存放pretrained模型,比如imagenet上的,以及读取文件的cache缓存 experiments 存放配置文件以及运行的log文件,另外这个目录下有scripts可以用end ...

  8. 16进制颜色转普通RGB

    做开发的会遇到很多时候UI给到的是16进制的颜色  然而很多时候我们需要把它转换成适合我们方法的RGB参数  当然通过网页转换也可以达到目的 但是我现在选择写一个分类来解决  一劳永逸~ 1.首先说下 ...

  9. Webdings和Wingdings字符码对应表

    刚才研究动网论坛代码,发现一个页面提示标记 i 感觉很神奇,看了半天才明白原来是一种叫“Webdings”的字体,其实很简单,只需要<font face='webdings' size=&quo ...

  10. 魔法变量*args 和 **kwargs

    其实并不是必须写成*args 和**kwargs. 只有变量前面的 *(星号)才是必须的. 你也可以写成*var 和**vars. 而写成*args 和**kwargs只是一个通俗的命名约定. *ar ...