bzoj1791,P4381-[IOI2008]Island【基环树,树形dp,单调队列dp,树的直径】

正题

评测记录:https://www.luogu.org/recordnew/lists?uid=52918&pid=P4381


题目大意

有n个岛,n条无向边(保证每个岛都有边连到)。走过的路和岛不可以重走,可以坐船。
坐船要求之前没有任何使用过的船加上道路可以到达那个点才可以坐船。

求最长可以走多远。


解题思路

首先这是一棵基环树森林,根据乘船的规定其实就是每棵基环树只可以走一次。这时候我们就可以发现答案就是每棵基环树的直径之和。然后我们考虑如何计算直径。

将环看作根。我们发现答案只有两种可能

  1. 经过根
  2. 不经过根

我们考虑不经过根的,计算出fxf_xfx(fxf_xfx表示x子树中离x最远的点的距离),然后用求树的直径的方法求出根以下每棵子树的直径并记录。然后我们计算经过根的。
假设环的节点为sss集合,那么答案就是max(fsi+fsj+disi∼j)max(f_{s_i}+f_{s_j}+dis_{i\sim j})max(fsi+fsj+disij)
dis表示环上i到j的最远距离。
我们可以通过单调队列dp计算出答案。


code

#include<cstdio>
#include<algorithm>
#include<queue>
#include<iostream>
#define N 1000010
#define lls long long
using namespace std;
struct node{int to,next,w;
}a[2*N];
int n,x,y,tot,t;
lls ls[N],in[N],cr[2*N],v[N],k[N],f[N],d[N],dis[2*N],ans,q[2*N];
void addl(int x,int y,int w)//加边
{a[++tot].to=y;a[tot].w=w;a[tot].next=ls[x];ls[x]=tot;in[y]++;
}
void dfs(int now,int k){v[now]=k;for (int i=ls[now];i;i=a[i].next){int y=a[i].to;if(!v[y]) dfs(y,k);}
}//标记联通块
void topsort(){int l=0,r=0;for (int i=1;i<=n;i++) if(in[i]==1) q[++r]=i;while(l<r) {int now=q[++l];for (int i=ls[now];i;i=a[i].next){int y=a[i].to;if(in[y]>1){in[y]--;d[v[now]]=max(d[v[now]],f[now]+f[y]+a[i].w);f[y]=max(f[y],f[now]+a[i].w);if(in[y]==1) q[++r]=y;}}}
}//拓扑排序求环
void dp(int t,int x){int m=0,y=x,i;do{cr[++m]=f[y];in[y]=1;for(i=ls[y];i;i=a[i].next){if(in[a[i].to]>1){dis[m+1]=dis[m]+a[i].w;y=a[i].to;break;}}}while(i);//预处理环的数据if(m==2){int l=0;for (int i=ls[y];i;i=a[i].next) if(a[i].to==x) l=max(l,a[i].w);d[t]=max(d[t],f[x]+f[y]+l);return;}//特批for(int i=ls[y];i;i=a[i].next){if(a[i].to==x) {dis[m+1]=dis[m]+a[i].w;break;}}//连接首尾for (int i=1;i<=m;i++){cr[i+m]=cr[i];dis[m+i]=dis[m+1]+dis[i];}//复制一份放在后面int l=1,r=0;q[++r]=1;for (int i=2;i<2*m;i++){while(l<=r&&i-q[l]>=m)l++;d[t]=max(dis[i]-dis[q[l]]+cr[i]+cr[q[l]],d[t]);while(l<=r&&cr[q[r]]+dis[i]-dis[q[r]]<=cr[i])r--;q[++r]=i;}//单调队列dp
}
int main(){scanf("%d",&n);for (int i=1;i<=n;i++){scanf("%d%d",&x,&y);addl(i,x,y);addl(x,i,y);}for (int i=1;i<=n;i++) if (!v[i]) dfs(i,++t);topsort();for (int i=1;i<=n;i++){if(in[i]>1&&!k[v[i]]) {k[v[i]]=1;dp(v[i],i);ans+=d[v[i]];}}printf("%lld",ans);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/323205.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【总结】找到自适合的学习方法

通过高中与大学的比较 我发现自己大学学的东西要比高中多很多&#xff0c;也要更加的充实。 说白了&#xff0c;其实我认为就是自己擅长与不擅长的学习方式罢了。 1、我更喜欢那种自由轻松一点的学习环境&#xff0c;高中把我压得太紧了&#xff08;老师喜欢提问&#xff09…

HttpClient的性能隐患

最近在进行开发过程中&#xff0c;基于都是接口开发&#xff0c;A站接口访问B接口接口来请求数据&#xff0c;而在这个过程中我们使用的是HttpClient这个框架&#xff0c;当然也是微软自己的框架&#xff0c;性能当前没有问题&#xff0c;但如果你直接使用官方的写法&#xff0…

P5022-旅行【基环树,dfs】

正题 评测记录:https://www.luogu.org/recordnew/lists?uid52918&pidP5022 题目大意 一棵树(可能是基环树)&#xff0c;从1出发&#xff0c;每到达一个新的点就记录下编号。求一种走法使得记录下来的编号字典序最小。 解题思路 我们先不考虑基环树。我们可以发现每次走…

【填坑】博客搬家造成的博客重复问题

原本我的博客数量是差不多八十几篇&#xff0c;昨天晚上一看&#xff0c;怎么变成一百三十多篇了。 惊讶之余有点不可思议&#xff0c;查了才发现原来有几十篇是重复的&#xff0c;后来删掉了一些&#xff0c;但还是有很多 有些也不是重复的&#xff0c;我从知乎发的东西也被搬…

[编程入门]猴子吃桃的问题

猴子吃桃问题。猴子第一天摘下若干个桃子&#xff0c;当即吃了一半&#xff0c;还不过瘾&#xff0c;又多吃了一个。 第二天早上又将剩下的桃子吃掉一半&#xff0c;又多吃一个。以后每天早上都吃了前一天剩下的一半零一个。 到第N天早上想再吃时&#xff0c;见只剩下一个桃子了…

Javafx的WebEgine执行window对象设置属性后为undefined

一、场景复现 window10 jdk1.8u221 package main;import javafx.application.Application; import javafx.beans.value.ObservableValue; import javafx.concurrent.Worker; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.layout.Sta…

P4168-[Violet]蒲公英【分块】

正题 评测记录:https://www.luogu.org/recordnew/lists?uid52918&pidP4168 题目大意 询问区间众数 解题思路 将数字离散化&#xff0c;然后分块。对于数组vi,j,kv_{i,j,k}vi,j,k​&#xff0c;表示i∼ji\sim ji∼j个块&#xff0c;kkk的个数。对于询问(l,r)(l,r)(l,r)&…

使用acs-engine在Azure中国区部署kubernetes集群详解

1. acs-engine简介 ACS是微软在2015年12月推出的一项基于容器的云端PaaS服务。说简单点&#xff0c;acs-engine就是一个ARM模板生成器&#xff0c;用户只需要配置几个简单的参数来描述容器集群的规格&#xff0c;然后acs-engine将这个容器集群描述文件转化成一组ARM&#xff08…

C++描述杭电OJ 2011.多项式求和 ||

C描述杭电OJ 2011.多项式求和 || Problem Description 多项式的描述如下&#xff1a; 1 - 1/2 1/3 - 1/4 1/5 - 1/6 … 现在请你求出该多项式的前n项的和。 Input 输入数据由2行组成&#xff0c;首先是一个正整数m&#xff08;m<100&#xff09;&#xff0c;表示测试实…

【Java】continue和break区别

先总结下&#xff1a;break先跳出整个大的循环&#xff0c;而continue跳出的是相对小的循环 也就是说他们的区别核心在于循环的大小 就举个例子吧&#xff0c;用for循环从一数到十&#xff0c;到五用上break和continue的区别 用break&#xff1a; public class test_01 { pu…

JS中令人发指的valueOf方法介绍

转载自 JS中令人发指的valueOf方法介绍 彭老湿近期月报里提到了valueOf方法&#xff0c;兴致来了翻了下ECMA5里关于valueOf方法的介绍&#xff0c;如下&#xff1a; 15.2.4.4 Object.prototype.valueOf ( ) When the valueOf method is called, the following steps are take…

P3203-[HNOI2010]弹飞绵羊【分块】

正题 评测记录:https://www.luogu.org/recordnew/lists?uid52918&pidP3203 题目大意 nnn个装置。到第iii个装置会被往前弹aia_iai​个。 两种操作 修改aia_iai​和询问从iii出发要多少次弹射可以弹出去。 解题思路 分块。对于每个点&#xff0c;维护要多少步弹出该块和弹…

Lyft的TypeScript实践

来自Lyft的前端工程师Mohsen Azimi介绍了Lyft向TypeScript转型的过程&#xff0c;说明JavaScript类型系统的重要性、为什么Lyft选择TypeScript以及他们的一些实践经验。以下内容翻译自作者的博客&#xff0c;查看原文TypeScript at Lyft。 在我刚刚成为JavaScript开发者的时候&…

【Python】Conda的安装

挖个坑&#xff0c;以后自己慢慢填&#xff1a;下载conda后无法使用 conda优势&#xff1a;conda将几乎所有的工具、第三方包都当做package对待&#xff0c;甚至包括python和conda自身&#xff01;因此&#xff0c;conda打破了包管理与环境管理的约束&#xff0c;能非常方便地…

C++描述杭电OJ 2014. 青年歌手大奖赛_评委会打分 ||

C描述杭电OJ 2014. 青年歌手大奖赛_评委会打分 || Problem Description 青年歌手大奖赛中&#xff0c;评委会给参赛选手打分。选手得分规则为去掉一个最高分和一个最低分&#xff0c;然后计算平均得分&#xff0c;请编程输出某选手的得分。 Input 输入数据有多组&#xff0c…

Java AIO 编程

转载自 java aio 编程 Java NIO (JSR 51)定义了Java new I/O API&#xff0c;提案2000年提出,2002年正式发布。 JDK 1.4起包含了相应的API实现。 JAVA NIO2 (JSR 203)定义了更多的 New I/O APIs&#xff0c; 提案2003提出&#xff0c;直到2011年才发布&#xff0c; 最终在JDK …

P1494-[国家集训队]小Z的袜子【分块优化莫队】

正题 评测记录:https://www.luogu.org/recordnew/lists?uid52918&pidP1494 题目大意 区间任意取两个数&#xff0c;求取到相同的数的概率。 解题思路 假设一个区间有x个y&#xff0c;那么两个都取到y的方案数是x∗(x−1)x*(x-1)x∗(x−1)&#xff0c;那么取到相同总共方…

通过Swashbukle给DotNet Core Web API 增加自动文档功能

DotNet Core Web API给开发者提供了一个很好的框架来开发Restful的API。那么这些API接口该如何管理起来呢&#xff1f;Swagger是一个很好的选择&#xff0c;Swagger不需要开发者额外去维护接口文档&#xff0c;只要开发者的接口遵循Restful的规范&#xff0c;Swagger就会根据AP…

【Python】urllib爬取动漫图片

首先附上需要爬取图片的网站&#xff0c;应该算是个冷门网站&#xff0c;够练手用的了&#xff0c;我的博客图片大部分来自于这里 二次元图片网站 筛选src里的数据 用par r’<img src"[^"].jpg">可以筛选出带有里面的内容 htmldasdas <img src"…

P4137-Rmq Problem/mex【莫队,分块】

正题 评测记录:https://www.luogu.org/recordnew/lists?uid52918&pidP4137 题目大意 求区间mex。 解题思路 开始发现aia_iai​很大&#xff0c;开不了桶。但是转念一想&#xff0c;如果ans>n1ans>n1ans>n1仅当前n1个都有&#xff0c;可是最多只有n个&#xff…