【BZOJ3677】[Apio2014]连珠线 换根DP
【BZOJ3677】[Apio2014]连珠线
Description
在列奥纳多·达·芬奇时期,有一个流行的童年游戏,叫做“连珠线”。不出所料,玩这个游戏只需要珠子和线,珠子从1到礼编号,线分为红色和蓝色。游戏开始时,只有1个珠子,而接下来新的珠子只能通过线由以下两种方式被加入:
1.Append(w,杪):-个新的珠子w和一个已有的珠子杪连接,连接使用红线。
2.Insert(w,u,v):-个新的珠子w加入到一对通过红线连接的珠子(u,杪)之间,并将红线改成蓝线。也就是将原来u连到1的红线变为u连到w的蓝线与W连到V的蓝线。
无论红线还是蓝线,每条线都有一个长度。而在游戏的最后,将得到游戏的最后得分:所有蓝线的长度总和。
现在有一个这个游戏的最终结构:你将获取到所有珠子之间的连接情况和所有连线的长度,但是你并不知道每条线的颜色是什么。
你现在需要找到这个结构下的最大得分,也就是说:你需要给每条线一个颜色f红色或蓝色),使得这种连线的配色方案是可以通过上述提到的两种连线方式操作得到的,并且游戏得分最大。在本题中你只需要输出最大的得分即可。
Input
第一行是一个正整数n,表示珠子的个数,珠子编号为1刭n。
接下来n-l行,每行三个正整数ai,bi(l≤ai10000),表示有一条长度为ci的线连接了珠子ai和珠子bi。
Output
输出一个整数,为游戏的最大得分。
Sample Input
1 2 10
1 3 40
1 4 15
1 5 20
Sample Output
HINT
数据范围满足1≤n≤200000。
题解:一开始想了个不换根的DP,结果错了。。。
先选择一个点当根,那么所有的蓝线一定是 父-子-孙 这样的。于是我们令g[x]表示当前点不是'子'的最大得分,f[x]表示当前点是'子'的最大得分,树形DP即可。
但是我们如何换根呢?我们需要维护f的最大值和次大值,然后就能搞了。
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn=200010;
int n,cnt,ans;
int to[maxn<<1],next[maxn<<1],val[maxn<<1],head[maxn],f1[maxn],g[maxn],f2[maxn];
inline void add(int a,int b,int c)
{
to[cnt]=b,val[cnt]=c,next[cnt]=head[a],head[a]=cnt++;
}
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+(gc^'0'),gc=getchar();
return ret*f;
}
void dfs1(int x,int fa)
{
f1[x]=f2[x]=-1<<30;
for(int y,i=head[x];i!=-1;i=next[i]) if(to[i]!=fa)
{
y=to[i],dfs1(y,x);
int fy=g[y]+val[i]-max(g[y],g[y]+f1[y]+val[i]);
if(fy>f1[x]) f2[x]=f1[x],f1[x]=fy;
else if(fy>f2[x]) f2[x]=fy;
g[x]+=max(g[y],g[y]+f1[y]+val[i]);
}
}
void dfs2(int x,int fa)
{
ans=max(ans,g[x]);
for(int y,i=head[x];i!=-1;i=next[i]) if(to[i]!=fa)
{
y=to[i];
int gx=g[x]-max(g[y],g[y]+f1[y]+val[i]),fx;
if(f1[x]==g[y]+val[i]-max(g[y],g[y]+f1[y]+val[i])) fx=f2[x];
else fx=f1[x];
g[y]+=max(gx,gx+fx+val[i]);
fx=gx+val[i]-max(gx,gx+fx+val[i]);
if(fx>f1[y]) f2[y]=f1[y],f1[y]=fx;
else if(fx>f2[y]) f2[y]=fx;
dfs2(y,x);
}
}
int main()
{
n=rd();
int i,a,b,c;
memset(head,-1,sizeof(head));
for(i=1;i<n;i++) a=rd(),b=rd(),c=rd(),add(a,b,c),add(b,a,c);
dfs1(1,0),dfs2(1,0);
printf("%d",ans);
return 0;
}
【BZOJ3677】[Apio2014]连珠线 换根DP的更多相关文章
- 洛谷$P3647\ [APIO2014]$连珠线 换根$dp$
正解:换根$dp$ 解题报告: 传送门! 谁能想到$9102$年了$gql$居然还没写过换根$dp$呢,,,$/kel$ 考虑固定了从哪个点开始之后,以这个点作为根,蓝线只可能是直上直下的,形如&qu ...
- [Bzoj3677][Apio2014]连珠线(树形dp)
3677: [Apio2014]连珠线 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 434 Solved: 270[Submit][Status] ...
- bzoj3677: [Apio2014]连珠线
Description 在列奥纳多·达·芬奇时期,有一个流行的童年游戏,叫做“连珠线”.不出所料,玩这个游戏只需要珠子和线,珠子从1到礼编号,线分为红色和蓝色.游戏 开始时,只有1个珠子,而接下来新的 ...
- bzoj 3677: [Apio2014]连珠线【树形dp】
参考:http://www.cnblogs.com/mmlz/p/4456547.html 枚举根,然后做树形dp,设f[i][1]为i是蓝线中点(蓝线一定是父子孙三代),f[i][0]为不是,转移很 ...
- 并不对劲的bzoj3677:p3647:[APIO2014]连珠线
题目大意 有一种生成\(n\)个点的树的方法为: 一开始有一个点,\(n-1\)次操作,每次可以有两种操作:1.选一个点,用一条红边将它与新点连接:2.将新点放在一条红边上,新点与这条红边两端点直接的 ...
- 题解 [APIO2014]连珠线
题解 [APIO2014]连珠线 题面 解析 首先这连成的是一棵树啊. 并且\(yy\)一下,如果钦定一个根, 那么这上面的蓝线都是爸爸->儿子->孙子这样的,因为像下图这样的构造不出来: ...
- 【LG3647】[APIO2014]连珠线
[LG3647][APIO2014]连珠线 题面 洛谷 题解 首先考虑一下蓝线连起来的情况,一定是儿子-父亲-另一个儿子或者是儿子-父亲-父亲的父亲. 而因为一开始只有一个点在当前局面上,将一条红边变 ...
- APIO2014 连珠线
题目链接:戳我 换根DP 由于蒟蒻不会做这个题,所以参考了大佬. 本来想的是有三种情况,一种是该节点不作为两个蓝线的中点(我们称这种不是关键节点),一种是该节点作为关键点.连两个子节点,一种是作为关键 ...
- Luogu P3647 [APIO2014]连珠线
题目 换根dp. 显然对于给定的一棵有根树,蓝线都不能拐弯. 设\(f_{u,0}\)表示\(u\)不是蓝线中点时子树内的答案,\(f_{u,1}\)表示\(u\)是蓝线中点时子树内的答案.(以\(1 ...
随机推荐
- 怎样统计分析CSDN博客流量
第一.IP.PV和UV各自是什么意思? IP.实际上也就是指独立IP,它的英文为Internet ***otocol,是独立IP数的意思.00:00-24:00同样IP地址记录一次.即使你有多台电脑. ...
- 网络配置br0 brtcl
1.brctl addbr br0 如果根据第3步,那这里不用写 2.brctl addif br0 eth0 如果第3步写了,这里也不用 这时候用ssh应该会断网... 3.设置 ...
- 又一个错误" Fatal error: Call to undefined function myabp_print_screenshot_all() "
xxx ( ! ) Fatal error: Call to undefined function myabp_print_screenshot_all() in D:\wamp\www\wp-con ...
- Juint测试
添加"Juint测试"组件: 之后不用写在main方法里面便可以直接测试:
- 利用层的table-row、table-cell属性进行页面布局
利用层的table-row.table-cell属性可以进行等高.宽度自适应页面布局,这是参看了<我所知道的几种display:table-cell的应用>及<基于display:t ...
- 很有必要了解的HTML嵌套规则
最近在重新学习HTML的知识,算是对HTML的一个重新认识吧!别小看了这东西,一切的网页可都是以它为基础的!下面就详细归纳一下HTML标签的嵌套规则吧,希望对大家有所帮助. XHTML的标签有许多:d ...
- Keypress - 捕获键盘输入的JavaScript库
Keypress 是一个强大的 JavaScript 库,用于捕获键盘输入.这是一个有非常特殊的功能的输入捕获库,它是很容易掌握和使用,并且不依赖第三方库.在网站开发中,经常会碰到需要处理键盘输入的场 ...
- 25+开源的在线购物软件(PHP, JavaScript 和 ASP.Net)
25 +免费开源的电子商务解决方案,提供了建立一个在线购物所有主要功能,并能够连接到一个支付处理系统1. Magento Magento是一套专业开源的PHP电子商务系统.Magento设计得非常灵活 ...
- ZooKeeper源码分析:Quorum请求的整个流程(转)
Quorum请求是转发给Leader处理,并且需要得一个Follower Quorum确认的请求.这些请求包括: 1)znode的写操作(OpCode.create,OpCode.delete,OpC ...
- “Chaos”的算法之Floyd算法
倘若我们要在计算机上建立一个交通咨询系统则可以采用图的结构来表示实际的交通网络.其实现最基本的功能,求出任意两点间的最短路径, 求最短路径的经典方法有很多种,最常用的便是迪杰斯特拉算法和佛洛依德(Fl ...