题解 P3647 [APIO2014]连珠线
题解
这里提供一种与其他题解不太相同的做法。
首先最后的树中只可能有这两种蓝线。
其次如果把一个为蓝线端点的点当作根,那就只有第一种情况。
因此一个做法是,枚举每个点为根时,根据第一种情况进行树形 dp。
具体的,设 \(w_{i,j}\) 表示 \(i,j\) 之间连线的权值,\(f_{i,0/1}\) 表示 \(1\) 为根时 \(i\) 的子树中,\(i\) 是/不是蓝线中点时答案的最大值。
\(f_{i,0}=\underset{v\in son_i}{\sum}\max(f_{v,0},f_{v,1}+w_{i,v})\)
\(f_{i,1}=f_{i,0}+\underset{v\in son_i}{\max}(f_{v,1}+w_{i,v}-f_{v,0})\)
接下来进行换根操作。
具体的,设 \(j\) 为 \(i\) 的某个儿子,\(dp_{i,0/1,j}\) 表示 \(1\) 为根时 \(i\) 的子树中,不考虑 \(j\) 的子树,\(i\) 是/不是蓝线中点时答案的最大值,\(g_{i,0/1}\) 表示 \(1\) 为根时整棵树中,不考虑 \(i\) 的子树,\(i\) 是/不是蓝线中点时答案的最大值。
答案即为 \(f_{i,0}+g_{i,0}\) 的最大值。
\(dp_{i,0,j}=\underset{v\in son_i,v\neq j}{\sum}\max(f_{v,0},f_{v,1}+w_{i,v})\)
\(dp_{i,1,j}=dp_{i,0,j}+\underset{v\in son_i,v\neq j}{\max}(f_{v,1}+w_{i,v}-f_{v,0})\)
\(g_{j,0}=\max(g_{i,0}+dp_{i,0,j},\max(g_{i,1}+dp_{i,0,j},g_{i,0}+dp_{i,1,j})+w_{i,j}\)
\(g_{j,1}=g_{i,0}+dp_{i,0,j}+w_{i,j}\)
具体实现用 vector 和最大次大值维护一下即可 \(O(1)\) 换根。
Code
#include<cstdio>
#include<vector>
#define inf 0x3f3f3f3f
using namespace std;
int n,edge_t=0,ans=0;
int la[200002]={},mx[200002],sec[200002];
int f[200002][2],g[200002][2];
vector<int> dp[200002][2];
struct aaa
{
int to,nx,val;
}edge[400002];
inline int max(int x,int y)
{
return x>y? x:y;
}
inline void add_edge(int x,int y,int z)
{
edge[++edge_t]=(aaa){y,la[x],z},la[x]=edge_t;
edge[++edge_t]=(aaa){x,la[y],z},la[y]=edge_t;
}
inline void dfs(int x,int fa)
{
mx[x]=sec[x]=-inf,f[x][0]=0;
for(int i=la[x],v,w,w1;i;i=edge[i].nx)
if((v=edge[i].to)!=fa)
{
dp[x][0].push_back(0),dp[x][1].push_back(0),dfs(v,x),f[x][0]+=(w1=max(f[v][0],f[v][1]+edge[i].val));
if((w=f[v][0]+edge[i].val-w1)>mx[x])sec[x]=mx[x],mx[x]=w;else if(w>sec[x])sec[x]=w;
}
f[x][1]=f[x][0]+mx[x];
}
inline void dfs1(int x,int fa)
{
int t=0;
for(int i=la[x],v;i;i=edge[i].nx)
if((v=edge[i].to)!=fa)
{
dp[x][0][t]=dp[x][1][t]=f[x][0]-max(f[v][0],f[v][1]+edge[i].val),dfs1(v,x);
if(mx[x]==f[v][0]+edge[i].val-max(f[v][0],f[v][1]+edge[i].val))dp[x][1][t]+=sec[x];else dp[x][1][t]+=mx[x];
++t;
}
}
inline void dfs2(int x,int fa)
{
int t=0;ans=max(ans,f[x][0]+g[x][0]);
for(int i=la[x],v;i;i=edge[i].nx)
if((v=edge[i].to)!=fa)
g[v][0]=max(g[x][0]+dp[x][0][t],max(g[x][1]+dp[x][0][t],g[x][0]+dp[x][1][t])+edge[i].val),g[v][1]=g[x][0]+dp[x][0][t]+edge[i].val,dfs2(v,x),++t;
}
int main()
{
g[1][0]=0,g[1][1]=-inf,scanf("%d",&n);
for(int i=1,x,y,z;i<n;++i)scanf("%d%d%d",&x,&y,&z),add_edge(x,y,z);
dfs(1,0),dfs1(1,0),dfs2(1,0),printf("%d",ans);
return 0;
}
原文地址:https://www.cnblogs.com/18Michael/p/15115378.html
- Angular企业级开发(7)-MVC之控制器
- Angular企业级开发(8)-控制器的作用域
- 使用jQuery Draggable和Droppable实现拖拽功能
- CSS魔法堂:重拾Border之——图片作边框
- Mobile Web中URL设计问题
- 使用root用户连接Ubuntu16.04时,提示SSH连接被拒绝
- CSS魔法堂:Box-Shadow没那么简单啦:)
- java操作redis: 将string、list、map、自定义的对象保存到redis中
- 运行第一个Docker容器-Docker for Web Developers(1)
- 手动实现jQuery Tools里面tab功能
- Angular企业级开发(9)-前后端分离之后添加验证码
- 基于thrift的微服务框架
- Sublime Text 快速格式化
- HTML中拖放介绍
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 简单聊聊红黑树(Red Black Tree)
- cocos creator探照灯效果实现
- servlet/filter/listener/interceptor区别与联系
- Linux下文本的简单处理(awk和sed)
- Spring4定时器 cronTrigger和simpleTrigger实现方法
- Tomcat远程调试
- IDEA建立Spring MVC Hello World 详细入门教程
- 嗯,手搓一个TinyPng压缩图片的WebpackPlugin也SoEasy啦
- Spring源码解析——核心类介绍
- IO之Basic IO
- 静态方法中注入bean
- 高通量数据中批次效应的鉴定和处理(五)- 预测并校正可能存在的混杂因素
- JVM 学习笔记(一)
- JVM 学习笔记(二)
- JVM 学习笔记(三)