BZOJ 1791 岛屿(环套树+单调队列DP)

题目实际上是求环套树森林中每个环套树的直径。

对于环套树的直径,可以先找到这个环套树上面的环。然后把环上的每一点都到达的外向树上的最远距离作为这个点的权值。

那么直径一定就是从环上的某个点开始,某个点结束的。

把环拆成链,定义dp[i]表示第i个点为结束点的最远距离,显然有dp[i]=val[j]+sum[i]-sum[j-1]+val[i].显然可以用单调队列优化这个DP。

剩下的就是这样依次统计每个环套树的直径之和。

 

对于环套树上找环可以借鉴最小树形图找环的技巧。

首先将边定向,保证每个点的出度为1.由于环套树的性质,这样从这颗树的任意点开始搜索,一定会回到原来访问过的点,在这个过程中记录好每个点的前驱。

就可以很easy的将这个环找出来。

 

#include <cstdio>  
#include <cstring>  
#include <algorithm>  
#include <stack>  
#include <cctype>  
#include <iostream>  
#define N 1050000  
using namespace std;  
inline int getc() {  static const int L = 1<<15;  static char buf[L],*S=buf,*T=buf;  if(S==T){  T=(S=buf)+fread(buf,1,L,stdin);  if(S==T)return EOF;  }  return *S++;  
}  
inline int getint() {  int c;  while(!isdigit(c = getc()));  int tmp = c-'0';  while(isdigit(c=getc()))  tmp=(tmp<<1)+(tmp<<3)+c-'0';  return tmp;  
}  
struct Syndra  
{  int u,v,len,next;  
}e[N];  
struct Fiona  
{  int edge,flag1,flag2;  long long temp,max1,max2;  
}s[N];  
int head[N],cnt,n;  
int visit[N],next[N],len[N];  
int i,j,k;  
long long sa[N],pre[N],ans;  
void add(int u,int v,int len)  
{  cnt++;  e[cnt].u=u;  e[cnt].v=v;  e[cnt].len=len;  e[cnt].next=head[u];  head[u]=cnt;  
}  
int que[N<<1];  
long long sum[N<<1],ret;  
long long dp(int num)  
{  int top,tail;  int u,b,star;  int et;  for(et=1;et<(num<<1);et++)  {  sum[et]=sum[et-1]+pre[(et-1)>=num?(et-1-num):(et-1)];  }  top=tail=0;  /* que[top]=0; for(et=1;et<(num<<1);et++) { while(et-que[top]>=num)top++; u=que[top]; ret=max(ret,sa[et>=num?et-num:et]+sa[u>=num?u-num:u]+sum[et]-sum[u]); b=que[tail]; que[++tail]=et; for(star=tail;star>top;b=que[star-1]) { if(sum[et]-sum[b]+sa[b]<sa[et]) { que[star]=b; que[--star]=et; } else break; } tail=star; } */  que[tail++]=0;  for(et=1;et<(num<<1);++et)  {  while(top<tail&&et-que[top]>=num)++top;  u=que[top];  ret=max(ret,sa[et>=num?et-num:et]+sa[u>=num?u-num:u]+sum[et]-sum[u]);  while(top<tail&&sa[et>=num?et-num:et]>=sa[que[tail-1]>=num?que[tail-1]-num:que[tail-1]]+sum[et]-sum[que[tail-1]])--tail;  que[tail++]=et;  }  return ret;  
}  
void build()  
{  cnt=1;  memset(head,0,sizeof(head));  memset(visit,0,sizeof(visit));  n=getint();  for(i=1;i<=n;i++)  {  next[i]=getint();  len[i]=getint();  add(next[i],i,len[i]);  }  
}  
stack<int>sk;  
int fa[N];  
void dfs(int x)  
{  if(s[x].edge==0)  {  sk.pop();  if(s[x].flag2)ret=max(ret,s[x].max1+s[x].max2);  if(visit[x]==-1)  return ;  x = sk.top();  {  int v,tt=s[x].edge;  v=e[tt].v;  visit[v]=i;  s[x].temp=s[v].max1+e[tt].len;  if(s[x].max1<s[x].temp)  {  if(s[x].flag1)s[x].max2=s[x].max1,s[x].flag2=1;  else s[x].flag1=1;  s[x].max1=s[x].temp;  }  else if(s[x].max2<s[x].temp)s[x].max2=s[x].temp,s[x].flag2=1;  s[x].edge=e[tt].next;  }  return ;  }  int v,tt=s[x].edge;  v=e[tt].v;  if(visit[v]==-1)  {  s[x].edge=e[tt].next;  return ;  }  fa[v]=x;  s[v].edge=head[v];  sk.push(v);  
}  
long long handle(int x)  
{  s[x].edge=head[x];  sk.push(x);  while(!sk.empty())  {  dfs(sk.top());  }  return s[x].max1;  
}/*handle(long long)+dfs(void)=dfs(long long)*/  
/*long long dfs(int x) 
{ int et,v,flag1,flag2; long long max1,max2; for(max1=max2=0,flag1=flag2=0,et=head[x];et;et=e[et].next) { v=e[et].v; if(visit[v]==-1)continue; temp=dfs(v)+e[et].len; visit[v]=i; if(max1<temp) { if(flag1)max2=max1,flag2=1; max1=temp; flag1=1; } else if(max2<temp)max2=temp,flag2=1; } if(flag2)ret=max(ret,max1+max2); return max1; 
}*/  
int main()  
{  int u,v;  build();  for(i=1;i<=n;i++)  {  if(!visit[i])  {  for(u=i;!visit[u];u=next[u])  {  visit[u]=i;  }  if(visit[u]==i)  {  ret=0;cnt=0;  visit[u]=-1;  for(v=next[u];v!=u;v=next[v])  {  visit[v]=-1;  }  v=u;  do{  pre[cnt]=len[v];  sa[cnt++]=handle(v);  v=next[v];  }while(v!=u);  ans+=dp(cnt);  }  }  }  cout<<ans;  return 0;  
}  
View Code

 

转载于:https://www.cnblogs.com/lishiyao/p/6613433.html

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

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

相关文章

什么是SAS

什么是SAS&#xff1f;简单的说&#xff0c;SAS是一种磁盘连接技术。它综合了现有并行SCSI和串行连接技术&#xff08;光纤通道、SSA、IEEE1394及InfiniBand等&#xff09;的优势&#xff0c;以串行通讯为协议基础架构&#xff0c;采用SCSI-3扩展指令集并兼容SATA设备&#xff…

C语言编程规范--常用缩写词

常用缩写词 缩 写 全 称 a addr address admin / adm administrator app application arg argument asm assemble asyn asynchronization avg average b bg background bk back bmp bitmap brk break btn button buf buffer c calc calculate ch…

netty系列之:JVM中的Reference count原来netty中也有

Python微信订餐小程序课程视频 https://edu.csdn.net/course/detail/36074 Python实战量化交易理财系统 https://edu.csdn.net/course/detail/35475 目录* 简介 ByteBuf和ReferenceCountedByteBuf的基本使用ByteBuf的回收ByteBuf的衍生方法ChannelHandler中的引用计数内存泄…

hdu区域赛在线热身赛 暨 第十二场组队赛

题目编号&#xff1a;hdu 4257~4266 (对应比赛题号1001~1010) 这是我们第十二场组队赛&#xff0c;在今天中午进行。 比赛刚开始&#xff0c;依然是由我的队友读题。还没看几题&#xff0c;就发现了好多题judge时长高达20秒&#xff0c;这真的有点给我们心理造成压力。不过&…

powerdesign相关

1.安装程序和汉化放百度云了 2.打印错误处理 http://jingyan.baidu.com/article/c45ad29cd84e4b051753e2c3.html 3.导出sql http://jingyan.baidu.com/article/7082dc1c48960ee40a89bd38.html 4.name和comment同步 http://blog.csdn.net/steveguoshao/article/details/16940347…

游戏名词

BUFF,DEBUFF: 增益状态&#xff0c;包括自己或者队友施加的&#xff0c;例如骑士的祝福&#xff0c;牧师的耐力精神&#xff0c;小德的爪子DEBUFF就是减益状态&#xff0c;例如你PK的时候法师的寒冰箭减速&#xff0c;盗贼的毒药&#xff0c;SS的腐蚀等等NPC&#xff1a; NPC就…

C语言编程规范--代码注释

目录 1、什么是Doxygen?. 3 2、撰写正确格式的批注... 4 2.1常用指令介绍... 4 2.2简述与详述的方式... 6 2.3文件头注释... 6 2.4版权注释... 6 2.5模块定义&#xff08;单独显示一页&#xff09;... 7 2.6分组定义&#xff08;在一页内分组显示&#xff09;... 8 2.7变量、宏…

Spring系列15:Environment抽象

Python微信订餐小程序课程视频 https://edu.csdn.net/course/detail/36074 Python实战量化交易理财系统 https://edu.csdn.net/course/detail/35475 本文内容 Environment抽象的2个重要概念Profile 的使用PropertySource 的使用 Environment抽象的2个重要概念 Environme…

U-Mail邮件服务系统任意文件上传+执行漏洞(runtime缺陷与验证绕过)

http://www.wooyun.org/bugs/wooyun-2010-061859转载于:https://www.cnblogs.com/hookjoy/p/4068326.html

Source Insight使用技巧

一、Source Insight实用技巧&#xff1a; Source Insight(下文的SI指的也是它)就是这样的一个东西&#xff1a;   Windows下开发人员的至爱&#xff0c;功能强大&#xff0c;界面友好。支持语法高亮、符号跳转&#xff0c;还支持函数调用关系图显示。这是一个专业的编程环境&…

剑指offer-翻转单词顺序列

剑指offer-翻转单词顺序列 题目描述 牛客最近来了一个新员工Fish&#xff0c;每天早晨总是会拿着一本英文杂志&#xff0c;写些句子在本子上。同事Cat对Fish写的内容颇感兴趣&#xff0c;有一天他向Fish借来翻看&#xff0c;但却读不懂它的意思。例如&#xff0c;“student. a …

私有化轻量级持续集成部署方案--05-持续部署服务-Drone(上)

Python微信订餐小程序课程视频 https://edu.csdn.net/course/detail/36074 Python实战量化交易理财系统 https://edu.csdn.net/course/detail/35475 提示&#xff1a;本系列笔记全部存在于 Github&#xff0c; 可以直接在 Github 查看全部笔记 持续部署概述 持续部署是能…

PS图像菜单下计算命令

PS图像菜单下计算命令通过通道的混合模式得到的选区非常精细&#xff0c;从而调色的时候过度非常好。功能十分强大。 下面用计算命令中的"相加"和"减去"模式做实例解析&#xff0c;这里通道混合模式和图层混合模式原理是一样的。 原图&#xff1a; 实例目…

LINQ系列:LINQ to XML操作

LINQ to XML操作XML文件的方法&#xff0c;如创建XML文件、添加新的元素到XML文件中、修改XML文件中的元素、删除XML文件中的元素等。 1. 创建XML文件 string xmlFilePath Server.MapPath("Data/Product.xml");XDocument doc new XDocument (new XDeclaration(&quo…

C语言编程规范

C语言编程规范 范 围: 本规范适用于公司内使用C语言编码的所有软件。本规范自发布之日起生效&#xff0c;以后新编写的和修改的 代码应遵守本规范。 简 介&#xff1a; 本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效 率、可移…

Ubuntu开发之旅一---安装初步

由于有一台小黑&#xff0c;老机器了&#xff0c;闲置时间不长不短&#xff0c;偶尔拿来用下&#xff0c;总感觉windows跑起来太费力&#xff0c;鉴于有过一段时间的Linux开发经验&#xff08;大概四个月左右&#xff09;&#xff0c;故抽空安装了一个ubuntu&#xff0c;原因有…

win10 VScode配置GCC(MinGW)

Python微信订餐小程序课程视频 https://edu.csdn.net/course/detail/36074 Python实战量化交易理财系统 https://edu.csdn.net/course/detail/35475 前提 安装 Visual Studio Code安装 C/C 扩展 for VS Code 也可以在vscode的extension界面搜索’c’查找插件安装 3. 获取最…

复制构造函数的用法及出现迷途指针问题

复制构造函数利用下面这行语句来复制一个对象&#xff1a; A (A &a) 从上面这句话可以看出&#xff0c;所有的复制构造函数均只有一个参数&#xff0c;及对同一个类的对象的引用 比如说我们有一个类A&#xff0c;定义如下&#xff1a; ?12345678910class A{public:A(int i…

Linux下压缩某个文件夹(文件夹打包)

为什么80%的码农都做不了架构师&#xff1f;>>> tar -zcvf /home/xahot.tar.gz /xahot tar -zcvf 打包后生成的文件名全路径 要打包的目录 例子&#xff1a;把/xahot文件夹打包后生成一个/home/xahot.tar.gz的文件。 zip 压缩方法&#xff1a; 压缩当前的文件夹 zi…

解决Warning: Cannot modify header information - headers already sent b...

解决Warning: require(E:\testwwwroot\cc06\wp-admin/wp-includes/compat.php) [function.require]: failed to open stream: No such file or directory in E:\testwwwroot\cc06\wp-admin\wp-settings.php on line 246Fatal error: require() [function.require]: Failed open…