Description 你将要游览一个有N个岛屿的公园。从每一个岛i出发,只建造一座桥。桥的长度以Li表示。公园内总共有N座桥。尽管每座桥由一个岛连到另一个岛,但每座桥均可以双向行走。同时,每一对这样的岛屿,都有一艘专用的往来两岛之间的渡船。 相对于乘船而言,你更喜欢步行。你希望所经过的桥的总长度尽可能的长,但受到以下的限制。:

可以自行挑选一个岛开始游览。

任何一个岛都不能游览一次以上。

无论任何时间你都可以由你现在所在的岛S去另一个你从未到过的岛D。

由S到D可以有以下方法:

步行:仅当两个岛之间有一座桥时才有可能。对于这种情况,桥的长度会累加到你步行的总距离

渡船:你可以选择这种方法,仅当没有任何桥和/或以前使用过的渡船的组合可以由S走到D(当检查是否可到达时,你应该考虑所有的路径,包括经过你曾游览过的那些岛)。

注意,你不必游览所有的岛,也可能无法走完所有的桥。 任务 编写一个程序,给定N座桥以及它们的长度,按照上述的规则,计算你可以走过的桥的最大长度。 限制 2 <= N <= 1,000,000 公园内的岛屿数目。 1<= Li <= 100,000,000 桥i的长度。

Input 第一行包含N个整数,即公园内岛屿的数目。岛屿由1到N编号。 随后的N行每一行用来表示一个岛。第i 行由两个以单空格分隔的整数,表示由岛i筑的桥。第一个整数表示桥另一端的岛,第二个整数表示该桥的长度Li。你可以假设对於每座桥,其端点总是位于不同的岛上。

Output 你的程序必须向标准输出写出包含一个整数的单一行,即可能的最大步行距离。 注:

对某些测试,答案可能无法放进32-bit整数,你要取得这道题的满分,可能需要用Pascal的int64或C/C++的long long类型。

在比赛环境运行Pascal程序,由标准输入读入64-bit数据比32-bit数据要慢得多,即使被读取的数据可以32-bit表示。我们建议把输入数据读入到32-bit数据类型。 评分 N不会超过4,000。

Sample Input 7 3 8 7 2 4 2 1 4 1 9 3 4 2 3

Sample Output 24

HINT

N点N边,这题就是棵基环树,然后题面就是要我们求各个基环树的直径之和。

如何求基环树的直径?首先,对于一个基环树,用dfs找到它所包含的环,然后从环上各点出发,求出子树内(不经过环上各点)最长链,并且可以顺便求出子树内直径,那么整个基环树的直径可能为所有子树直径最大值。

当然,还可能有其他的情况,可能是环上两点的距离加上两点的子树内最长链。这个我们可以破环成链,翻倍后使用单调队列去维护

然后这题完全自己yy出来的,于是BZOJ跑了140MB……可能是BZOJ比较那啥吧(其他OJ都没有跑过128MB来着)

/*program from Wolfycz*/

#include

#include

#include

#include

#include

#define inf 0x7f7f7f7f

using namespace std;

typedef long long ll;

typedef unsigned int ui;

typedef unsigned long long ull;

inline int read(){

int x=0,f=1;char ch=getchar();

for (;ch'9';ch=getchar())if (ch=='-') f=-1;

for (;ch>='0'&&ch<='9';ch=getchar())x=(x<<1)+(x<<3)+ch-'0';

return x*f;

}

inline void print(int x){

if (x>=10)print(x/10);

putchar(x%10+'0');

}

const int N=1e6;

int pre[(N<<1)+10],now[N+10],child[(N<<1)+10],val[(N<<1)+10];

int Frm[N+10],vis[N+10],A[(N<<1)+10],h[(N<<1)+10],v[N+10];

ll B[(N<<1)+10],F[N+10],Len;

int tot,Bgn,End;

void join(int x,int y,int z){pre[++tot]=now[x],now[x]=tot,child[tot]=y,val[tot]=z;}

void insert(int x,int y,int z){join(x,y,z),join(y,x,z);}

void dfs(int x,int fa){

if (End&&Bgn&&vis[x])return;

vis[x]=1;

for (int p=now[x],son=child[p];p;p=pre[p],son=child[p]){

if (son==fa)continue;

if (vis[son]){

End=son,Bgn=x;

//因为环上最后一条边会被扫两次,所以End和Bgn的赋值会显得有些奇怪

continue;

}

dfs(son,x),v[son]=val[p],Frm[son]=x;

}

}

void get_F(int x,int fa){

ll G=0;

for (int p=now[x],son=child[p];p;p=pre[p],son=child[p]){

if (son==fa||vis[son]==2)continue;

get_F(son,x);

if (F[son]+val[p]>F[x])G=F[x],F[x]=F[son]+val[p];

elseif (F[son]+val[p]>G)G=F[son]+val[p];

}

Len=max(Len,F[x]+G);

}

ll work(int x){

Bgn=End=0;

dfs(x,0);

for (int p=now[Bgn],son=child[p];p;p=pre[p],son=child[p])if (son==End)v[Bgn]=val[p];

vis[Bgn]=2;

for (int tmp=End;tmp!=Bgn;tmp=Frm[tmp])vis[tmp]=2;

Len=0,get_F(Bgn,0);

int m=0,head=1,tail=1;

//后面破环成链,单调队列优化,写的有点丑。。。

for (int tmp=End;tmp!=Bgn;tmp=Frm[tmp])get_F(tmp,0),A[++m]=tmp;

A[++m]=Bgn,B[1]=0;

for (int i=1;i

for (int i=1;i<=m;i++)A[m+i]=A[i],B[m+i]=B[i]+B[m]+v[A[m]];

h[head]=1;

for (int i=1;i<=m<<1;i++){

while (head<=tail&&i-h[head]>=m)head++;

Len=max(Len,F[A[i]]+F[A[h[head]]]+B[i]-B[h[head]]);

while (head<=tail&&F[A[h[tail]]]-B[h[tail]]

h[++tail]=i;

}

return Len;

}

int main(){

int n=read();ll Ans=0;

for (int i=1;i<=n;i++){

int x=read(),y=read();

insert(i,x,y);

}

for (int i=1;i<=n;i++)if (!vis[i])Ans+=work(i);

printf("%lld\n",Ans);

return 0;

}

岛屿周长c语言,[IOI2008]Island 岛屿相关推荐

  1. bzoj1791: [Ioi2008]Island 岛屿 单调队列优化dp

    1791: [Ioi2008]Island 岛屿 Time Limit: 20 Sec  Memory Limit: 162 MB Submit: 1826  Solved: 405 [Submit] ...

  2. 岛屿周长c语言,岛屿的周长 --leetcode刷题,golang实现

    给定一个包含 0 和 1 的二维网格地图,其中 1 表示陆地 0 表示水域. 网格中的格子水平和垂直方向相连(对角线方向不相连).整个网格被水完全包围,但其中恰好有一个岛屿(或者说,一个或多个表示陆地 ...

  3. [ioi2008]Island 岛屿

    题目描述 你将要游览一个有N个岛屿的公园.从每一个岛i出发,只建造一座桥.桥的长度以Li表示.公园内总共有N座桥.尽管每座桥由一个岛连到另一个岛,但每座桥均可以双向行走.同时,每一对这样的岛屿,都有一 ...

  4. Swif算法学习-岛屿周长问题

    岛屿周长问题 一 问题描述 给定一个包含 0 和 1 的二维网格地图,其中 1 表示陆地 0 表示水域. 网格中的格子水平和垂直方向相连(对角线方向不相连).整个网格被水完全包围,但其中恰好有一个岛屿 ...

  5. P4381 [IOI2008]Island

    P4381 [IOI2008]Island 题意: 给你一棵基环树森林,求出基环树的直径之和. 题解: 对于基环树,我们将环看作根,那么直径有两种情况:: 1.不经过环,也就是环上某个点的子树内部,对 ...

  6. 岛屿问题 通用解-463.岛屿周长-200.岛屿数量-695.岛屿的最大面积-827.最大人工岛

    文章目录 岛屿问题 如何在网格上做DFS(通用解) 463.岛屿的周长 题目 题解 -通用模板 题解2 200.岛屿数量 题目 题解 695.岛屿的最大面积 题目 题解 827.最大人工岛 题目 题解 ...

  7. Leetcode695.Max Area of Island岛屿的最大面积

    给定一个包含了一些 0 和 1的非空二维数组 grid , 一个 岛屿 是由四个方向 (水平或垂直) 的 1 (代表土地) 构成的组合.你可以假设二维矩阵的四个边缘都被水包围着. 找到给定的二维数组中 ...

  8. 岛屿的个数java_LeetCode 200:岛屿数量 Number of Islands

    题目: 给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量.一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的.你可以假设网格的四个边均被水包围. Given ...

  9. 岛屿最大面积 leetcode Java_LeetCode:岛屿的最大面积

    岛屿的最大面积 题目叙述: 给定一个包含了一些 0 和 1的非空二维数组 grid , 一个 岛屿 是由四个方向 (水平或垂直) 的 1 (代表土地) 构成的组合.你可以假设二维矩阵的四个边缘都被水包 ...

  10. 计算长方形的面积 周长 C语言,c语言计算长方形的面积和周长

    用c语言计算长方形的面积和周长 计算长方形的面积和周长 #include "stdio.h" main() { intchang; intkuan; intmianji; intz ...

最新文章

  1. springboot视图解析器
  2. linux rabbitmq安装包,Linux安装RabbitMQ
  3. Entity Component System
  4. neo4j 4.1.8版本安装图算法包
  5. SAP Engagement Center的ShellCarousel控件control
  6. c语言 char c1,c2; for (c1='0',C语言-5循环结构(PPT)复习课程.ppt
  7. 10.深度学习练习:Convolutional Neural Networks: Step by Step(强烈推荐)
  8. EntityManager:seam新手必读(一)
  9. 双11猫晚直播:看阿里文娱如何“擒住”高并发、多视角、低卡顿!
  10. Android调用系统发送短信界面
  11. Bloomberg监控系统的标准化和扩展
  12. 从草图到人脸:这篇SIGGRAPH2020论文帮你轻松画出心中的「林妹妹」,开源「计图」实现代码...
  13. nmake命令行编译Qt项目
  14. C语言算三角形外心坐标,三角形外心坐标公式(含C语言代码)
  15. 初识大数据 小孩子都懂的大数据
  16. c语言scanf用法
  17. cesium 实现地形挖洞的拖动效果
  18. 训练3.21(CF 543B Destroying Roads)
  19. 台式计算机蓝牙如何安装,台式电脑没有蓝牙怎么安装
  20. 如何运用dos命令进入指定目录

热门文章

  1. 用数据分析头部微信公众号到底有多牛
  2. 神经网络中_,predicted=中_,的作用
  3. 益聚星荣|网络主播雪梨、林珊珊偷逃税被罚,2个月前已进行立案检查
  4. 电子邮箱免费注册,个人邮箱申请哪个好?微信邮箱客户端这个好用
  5. vue的报错 error Trailing spaces not allowed
  6. Python入门(每日学习打卡7.12)
  7. 【渝粤题库】陕西师范大学100131大学英语(二) 作业 (高起本、高起专)
  8. 只有VOB 文件,怎样使用IfoEdit生成烧制DVD所需的IFO、BUP文件!
  9. 51CTO学院三周年-我的rhce7认证之路
  10. 云联惠创业经营者认证_广州公安打掉云联惠涉传销组织 零壹财经曾发文警示...