APIO2014 连珠线
题目链接:戳我
换根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 连珠线的更多相关文章
- 【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个珠子,而接下来新的 ...
- bzoj 3677: [Apio2014]连珠线【树形dp】
参考:http://www.cnblogs.com/mmlz/p/4456547.html 枚举根,然后做树形dp,设f[i][1]为i是蓝线中点(蓝线一定是父子孙三代),f[i][0]为不是,转移很 ...
- Luogu P3647 [APIO2014]连珠线
题目 换根dp. 显然对于给定的一棵有根树,蓝线都不能拐弯. 设\(f_{u,0}\)表示\(u\)不是蓝线中点时子树内的答案,\(f_{u,1}\)表示\(u\)是蓝线中点时子树内的答案.(以\(1 ...
- 洛谷$P3647\ [APIO2014]$连珠线 换根$dp$
正解:换根$dp$ 解题报告: 传送门! 谁能想到$9102$年了$gql$居然还没写过换根$dp$呢,,,$/kel$ 考虑固定了从哪个点开始之后,以这个点作为根,蓝线只可能是直上直下的,形如&qu ...
- 洛谷 P3647 [APIO2014]连珠线(换根 dp)
题面传送门 题意: 桌子上有 \(1\) 个珠子,你要进行 \(n-1\) 次操作,每次操作有以下两种类型: 拿出一个新珠子,并选择一个桌子上的珠子,在它们之间连一条红线 选择两个由红线相连的珠子 \ ...
随机推荐
- postman的使用方法详解
Collections:在Postman中,Collection类似文件夹,可以把同一个项目的请求放在一个Collection里方便管理和分享,Collection里面也可以再建文件夹.如果做API文 ...
- 如何设置tomcat,直接通过IP 访问
找到tomcat的主目录,进入conf文件夹,找到server.xml文件,并打开: 修改tomcat的监听端口为80端口: 在server.xml文件中找到: <Connector por ...
- JAVA中集合转数组遍历
JAVA中集合的遍历的一种方法时集合转数组遍历,也是就调用Collection中的toArray(). 代码: public static void main(String[] args) { ...
- HP发送HTTP POST请求 返回结果
HP发送HTTP POST请求 返回结果 <?php $srv_ip = '192.168.10.188';//你的目标服务地址或频道.$srv_port = 80;$url = '/demo/ ...
- Oracle VM VirtualBox 部署CS devcloud2 开发环境
Setting up (VirtualBox) 1. Get the new DevCloud 2.0 virtual appliance. The new image was created usi ...
- Monkey&Monkey Runner使用
adb shell monkey -p com.ajb.sp -s 500 --ignore-crashes --ignore-timeouts --monitor-native-crashes -v ...
- 最近工作的一点小tips
最近工作比较忙,但也积累了一些小tips,比较杂,不成系统,也并不很深入,就开一篇笼统的先记录一下,以后再深入挖掘. 1.-webkit-tap-highlight-color -webkit-tap ...
- [C++] How to prevent memory leaks
How to prevent memory leaks ? overload new/delete
- code3027 线段覆盖2
dp 数据:d[i].a d[i].b d[i].v 分别表示第i条线段的起始点,结束点,价值 先按d[i].b排好序 dp[i]表示前i条线段的最大价值 方程: dp[i]=max{ dp[i-1] ...
- 高性能python编程之协程(stackless)-乾颐堂
我们都知道并发(不是并行)编程目前有四种方式,多进程,多线程,异步,和协程. 多进程编程在python中有类似C的os.fork,当然还有更高层封装的multiprocessing标准库,在之前写过的 ...