3677: [Apio2014]连珠线


Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 434  Solved: 270
[Submit][Status][Discuss]

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



Sample Output


 

HINT


数据范围满足1≤n≤200000。

分析:


一开始以为定义状态f[i][0/1]表示第i个点是不是中心点乱树形dp就可以了,结果考完只有10分

原因:这个题加入有顺序,任何时刻加入的点都是一个联通块。
 
这样我们就要枚举根节点,并且合并只能合并 父-子-孙。
 
然后复杂度是O(n^2)的。
 
我们可以优化一下换根,不用每次换根都去枚举,如果每次只枚举当前根节点没当过根的儿子,会重新dp的只有两个点,换根复杂度O(1)
 
所以总复杂度O(n)
 
然后一开始用了vector啥的,bzoj上过了,cena上一首凉凉送给stl,被迫看了别人的代码改出来QAQ
 

AC代码:


# include <iostream>
# include <cstdio>
using namespace std;
const int N = 3e5 + ;
const int inf = 0x3f3f3f3f;
int head[N],dt,n,ans,f1[N],f2[N],g[N];
struct Edge{
int to,nex,w;
}edge[N << ];
void AddEdge(int u,int v,int w)
{
edge[++dt] = (Edge){v,head[u],w};
head[u] = dt;
}
void dfs(int u,int pre)
{
f1[u] = f2[u] = -inf;int t;
for(int i = head[u];i;i = edge[i].nex)
{
if(edge[i].to == pre)continue;
dfs(edge[i].to,u);
t = g[edge[i].to] + edge[i].w - max(g[edge[i].to],g[edge[i].to] + f1[edge[i].to] + edge[i].w);
if(t > f1[u])f2[u] = f1[u],f1[u] = t;
else if(t > f2[u])f2[u] = t;
g[u] += max(g[edge[i].to],g[edge[i].to] + f1[edge[i].to] + edge[i].w);
}
}
void Dfs(int u,int pre)
{
ans = max(ans,g[u]);int s,t,c;
for(int i = head[u];i;i = edge[i].nex)
{
if(edge[i].to == pre)continue;
s = g[u] - max(g[edge[i].to],g[edge[i].to] + f1[edge[i].to] + edge[i].w);
t = g[edge[i].to] + edge[i].w - max(g[edge[i].to],g[edge[i].to] + f1[edge[i].to] + edge[i].w);
if(f1[u] == t)c = f2[u];else c = f1[u];
g[edge[i].to] += max(s,s + c + edge[i].w);
t = s + edge[i].w - max(s,s + c + edge[i].w);
if(t > f1[edge[i].to])f2[edge[i].to] = f1[edge[i].to],f1[edge[i].to] = t;
else if(t > f2[edge[i].to])f2[edge[i].to] = t;
Dfs(edge[i].to,u);
}
}
int main()
{
freopen("beads.in","r",stdin);
freopen("beads.out","w",stdout);
scanf("%d",&n);int x,y,z;
for(int i = ;i < n;i++)
{
scanf("%d %d %d",&x,&y,&z);
AddEdge(x,y,z);AddEdge(y,x,z);
}
dfs(,-);Dfs(,-);
printf("%d\n",ans);
fclose(stdin);
fclose(stdout);
return ;
}

[Bzoj3677][Apio2014]连珠线(树形dp)的更多相关文章

  1. bzoj3677: [Apio2014]连珠线

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

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

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

  3. 题解 [APIO2014]连珠线

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

  4. 【LG3647】[APIO2014]连珠线

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

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

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

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

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

  7. APIO2014 连珠线

    题目链接:戳我 换根DP 由于蒟蒻不会做这个题,所以参考了大佬. 本来想的是有三种情况,一种是该节点不作为两个蓝线的中点(我们称这种不是关键节点),一种是该节点作为关键点.连两个子节点,一种是作为关键 ...

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

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

  9. 并不对劲的bzoj3677:p3647:[APIO2014]连珠线

    题目大意 有一种生成\(n\)个点的树的方法为: 一开始有一个点,\(n-1\)次操作,每次可以有两种操作:1.选一个点,用一条红边将它与新点连接:2.将新点放在一条红边上,新点与这条红边两端点直接的 ...

随机推荐

  1. PAT (Basic Level) Practise (中文)-1030. 完美数列(25)

    PAT (Basic Level) Practise (中文)-1030. 完美数列(25)   http://www.patest.cn/contests/pat-b-practise/1030 给 ...

  2. Windows10安装MariaDB

    截至写这篇博客为止,MariaDB官方的稳定版本为,详情访问官方地址:https://downloads.mariadb.org/ 安装之前先简单说一下MariaDB:         MariaDB ...

  3. css3如何实现click后页面过渡滚动到顶部

    var getTop = document.getElementById("get-top"); var head = document.getElementById(" ...

  4. POJ-1061 青蛙的约会 (扩展欧几里得)

    [题目描述] 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件很重要的事情,既没有 ...

  5. MFC中关于子进程创建和关闭操作

    创建子进程 PROCESS_INFORMATION ProcessInfo; STARTUPINFO StartupInfo; //This is an [in] parameter ZeroMemo ...

  6. 使用adb命令启查看已安装的Android应用的versionCode、versionName

    列出已经安装的应用 adb shell pm list package C:\Users\CJTDEV003>adb shell pm list package package:com.sams ...

  7. 使用pipework将Docker容器桥接到本地网络环境中

    在使用Docker的过程中,有时候我们会有将Docker容器配置到和主机同一网段的需求.要实现这个需求,我们只要将Docker容器和主机的网卡桥接起来,再给Docker容器配上IP就可以了.pipew ...

  8. matlab调用自己写的函数时报错: reference to a cleared variable

    原因是在自己写的函数中加了clear. 解决办法:自己定义的函数中不能加clear,可以加clc;

  9. oracle表空间,分区表,以及索引的总结

    表空间: Oracle的UNDOTBS01.DBF文件太大的解决办法 1..禁止undo tablespace自动增长 alter   database   datafile   'full_path ...

  10. 在windows下安装flex和bison、GCC

    学习Stellar-core 需要依赖项flex .bison .gcc三个依赖项 下载得网址:链接: https://pan.baidu.com/s/1mitCLcs 密码: 3jaj   通过 w ...