[题目链接]

https://www.lydsy.com/JudgeOnline/problem.php?id=1791

[算法]

不难看出,要求的是这个基环树森林中每棵基环树的直径之和

[代码]

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e6 + ; struct edge
{
int to,w,nxt;
} e[MAXN << ]; int i,v,w,tot,n,u,cnt;
int degree[MAXN],belong[MAXN],head[MAXN];
long long d[MAXN],f[MAXN],a[MAXN << ],sum[MAXN << ];
long long ans;
bool cal[MAXN]; inline void addedge(int u,int v,int w)
{
tot++;
e[tot] = (edge){v,w,head[u]};
head[u] = tot;
}
inline void bfs(int u,int t)
{
int i,cur,v,w;
queue< int > q;
belong[u] = t;
q.push(u);
while (!q.empty())
{
cur = q.front();
q.pop();
for (i = head[cur]; i; i = e[i].nxt)
{
v = e[i].to;
w = e[i].w;
if (!belong[v])
{
belong[v] = t;
q.push(v);
}
}
}
}
inline void topsort()
{
int i,u,v,w;
queue< int > q;
for (i = ; i <= n; i++)
{
if (degree[i] == )
q.push(i);
}
while (!q.empty())
{
u = q.front();
q.pop();
for (i = head[u]; i; i = e[i].nxt)
{
v = e[i].to;
w = e[i].w;
if (degree[v] > )
{
d[belong[u]] = max(d[belong[u]],f[u] + f[v] + w);
f[v] = max(f[v],f[u] + w);
if ((--degree[v]) == ) q.push(v);
}
}
}
}
inline void dp(int t,int x)
{
long long i,l,r,y = x,m = ,v,w;
static int q[MAXN << ];
do
{
a[++m] = f[y];
degree[y] = ;
for (i = head[y]; i; i = e[i].nxt)
{
v = e[i].to;
w = e[i].w;
if (degree[v] > )
{
y = v;
sum[m + ] = sum[m] + w;
break;
}
}
} while(i);
if (m == )
{
l = ;
for (i = head[y]; i; i = e[i].nxt)
{
v = e[i].to;
w = e[i].w;
if (v == x) l = max(l,w);
}
d[t] = max(d[t],f[x] + f[y] + l);
return;
}
for (i = head[y]; i; i = e[i].nxt)
{
v = e[i].to;
w = e[i].w;
if (v == x)
{
sum[m + ] = sum[m] + w;
break;
}
}
for (i = ; i < m; i++)
{
a[m + i] = a[i];
sum[m + i] = sum[m + ] + sum[i];
}
q[l = r = ] = ;
for (i = ; i <= * m - ; i++)
{
while (l <= r && i - q[l] >= m) l++;
d[t] = max(d[t],a[q[l]] + a[i] + sum[i] - sum[q[l]]);
while (l <= r && a[q[r]] - sum[q[r]] <= a[i] - sum[i]) r--;
q[++r] = i;
}
}
int main()
{ scanf("%d",&n);
for (u = ; u <= n; u++)
{
scanf("%d%d",&v,&w);
addedge(u,v,w);
addedge(v,u,w);
degree[u]++; degree[v]++;
}
for (i = ; i <= n; i++)
{
if (!belong[i])
bfs(i,++cnt);
}
topsort();
for (i = ; i <= n; i++)
{
if (degree[i] > && !cal[belong[i]])
{
cal[belong[i]] = true;
dp(belong[i],i);
ans += d[belong[i]];
}
}
printf("%lld\n",ans); return ; }

[IOI 2008] Island的更多相关文章

  1. 「BZOJ 1791」「IOI 2008」Island「基环树」

    题意 求基环树森林所有基环树的直径之和 题解 考虑的一个基环树的直径,只会有两种情况,第一种是某个环上结点子树的直径,第二种是从两个环上结点子树内的最深路径,加上环上这两个结点之间的较长路径. 那就找 ...

  2. 『Island 基环树直径』

    Island(IOI 2008) Description 你准备浏览一个公园,该公园由 N 个岛屿组成,当地管理部门从每个岛屿 i 出发向另外一个岛屿建了一座长度为 L_i 的桥,不过桥是可以双向行走 ...

  3. HDUOJ-------2493Timer(数学 2008北京现场赛H题)

    Timer Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Subm ...

  4. 在离线环境中发布.NET Core至Windows Server 2008

    在离线环境中发布.NET Core至Windows Server 2008 0x00 写在开始 之前一篇博客中写了在离线环境中使用.NET Core,之后一边学习一边写了一些页面作为测试,现在打算发布 ...

  5. Windows Server 2008 R2常规安全设置及基本安全策略

    这篇文章主要介绍了Windows Web Server 2008 R2服务器简单安全设置,需要的朋友可以参考下 用的腾讯云最早选购的时候悲催的只有Windows Server 2008 R2的系统,原 ...

  6. Windows Server 2008 小操作汇总

    用惯了Windows2003,去配置2008的时候还真有点摸不着头脑.干脆把有用到的都列在这里,方便后续查找. 一.安装IIS.Telnet      点击:开始 -> 管理工具 -> 服 ...

  7. Windows 2008 R2 安装sp1时未知错误的解决办法

    最近在为Windows Server 2008 R2 打sp1补丁时出现“发生未知错误”,详细信息错误:0x800f0818: google后找到解决问题步骤,参照:http://www.wikiho ...

  8. 如何在Windows Server 2008 R2没有磁盘清理工具的情况下使用系统提供的磁盘清理工具

    今天,刚好碰到服务器C盘空间满的情况,首先处理了临时文件和有关的日志文件后空间还是不够用,我知道清理C盘的方法有很多,但今天只分享一下如何在Windows Server 2008 R2没有磁盘清理工具 ...

  9. [vs2008]Visual Studio 2008 SP1添加或删除功能提示查找SQLSysClrTypes.msi文件

    前言 今天接到领导布置的一个任务,是之前同事负责的项目.离职了,现在客户有些地方需要修改,由于我之前参与过,就落在我的头上了. 然后我就把代码弄了过来,打开发现其中需要用到水晶报表.(我觉得不好用,不 ...

随机推荐

  1. 快速搭建tab

    1. 布局文件代码: <?xml version="1.0" encoding="utf-8"?> <android.support.v4.a ...

  2. 查看Oracle数据库表空间大小,是否需要增加表空间的数据文件

    在数据库管理中,磁盘空间不足是DBA都会遇到的问题,问题比较常见. --1查看表空间已经使用的百分比 Sql代码 select a.tablespace_name,a.bytes/1024/1024 ...

  3. C# 跨平台换行符 System.Environment.NewLine

    C# 跨平台换行符 System.Environment.NewLine

  4. jquery的attr和prop

    注意不同版本的attr和prop,attr适用于自定义dom值,prop适用于带有固有属性

  5. CorelDRAW关于使用鼠标的5个技巧分享

    CorelDRAW重度依赖者对快捷键和技巧性的操作爱不释手.本文我们介绍使用CorelDRAW关于鼠标操作的5个技巧,这是五种超快,非常有效,特别实用的技巧,如果每天的工作结合这些技巧的使用,效率会大 ...

  6. matlab学习下拉菜单Pop-Up Menu的基本用法

    创建下拉菜单,修改string的属性,tag改为kj1,value值如果是1就显示第一行的sin(x),是几就显示第几行 %可以更改value值var=get(handles.kj1,'value') ...

  7. BZOJ 1060: [ZJOI2007]时态同步 树上问题 + 贪心

    Description 小Q在电子工艺实习课上学习焊接电路板.一块电路板由若干个元件组成,我们不妨称之为节点,并将其用数 字1,2,3….进行标号.电路板的各个节点由若干不相交的导线相连接,且对于电路 ...

  8. malloc实现机制、缓冲机制、文件操作、mmap虚拟地址(day06)

    一.malloc的实现机制(缓冲机制) 库函数跟系统调用之间的关系 什么是缓冲? 内存分配的原理. 封装 函数A的实现代码中调用了函数B.函数B的功能是函数A主要的功能,这样就说函数A封装了函数B. ...

  9. [Ynoi2014]不归之人与望眼欲穿的人们

    题目大意: 给定一个序列,每次单点修改一个数,或给定$x$,询问最短的or起来大于等于$x$的区间的长度(不存在输出-1). 解题思路: 在太阳西斜的这个世界里,置身天上之森.等这场战争结束之后,不归 ...

  10. 当svn检出项目检出一半时停止,如何继续检出

    1.当svn检出项目时,发现中断,又不想重新检出可以在已检出的项目目录下右键 2.然后点击 之后直接update你的项目就可以了