Description

Serpent(水 蛇)生活的地方有N个水坑,编号为0,...,N - 1,有M条双向小路连接这些水坑。每两个水坑之间至多有一条路径(路径包含一条或多条小路)相互连接,有些水坑之间根本无法互通(即M ≤ N-1 )。Serpent走过每条小路需要一个固定的天数,不同的小路需要的天数可能不同。Serpent的朋友袋鼠希望新修 N - M - 1条小路,让Serpent可以在任何两个水坑间游走。袋鼠可以在任意两个水坑之间修路,Serpent通过每条新路的时间都是L天。袋鼠希望找到一种修 路方式使得修路之后Serpent在每两个水坑之间游走的最长时间最短。

举例说明

上图中有12个水坑8条小路( N = 12, M = 8)。假如L = 2 ,即Serpent通过任何一条新路都需要2天。那么,袋鼠可以修建3条新路:
水坑1和水坑2之间;
水坑1和水坑6之间;
水坑4和水坑10之间。

上图显示了修路后的最终状态。从水坑0走到水坑11的时间最长,需要18天。这是 最佳结果,无论袋鼠如何选择修路方式,总会存在一些水坑对,Serpent需要18天 或者更长时间从其中一个走到另一个。

Input

N : 水坑的数目。
M : 原本存在的小路的数目。
L : Serpent通过新修的路经的时间。
A, B 和 T: 三个包含M个元素的数组,分别表示每条小路的两个端点和通过这条小路的时间。例如,第i条小路连接水坑 A[i-1]和水坑B[i-1],通过这条小路的时间是T[i-1]天。

Output

如上所述,表示游走于两个距离最远的水坑之间所需的时间。

Sample Input

12 8 2
0 8 4
8 2 2
2 7 4
5 11 3
5 1 7
1 3 1
1 9 5
10 6 3

Sample Output

18

HINT

n <= 500000

正解:树形DP

解题报告:

  考场上写的正解,没考虑很多细节,炸到22分。

  看了这道题之后感性认识肯定搞出每个连通块内离连通块内所有点中最远距离最小的那个点,有点类似于重心,显然2遍dfs可做。然后就是考虑如何拼接这些连通块。

  很容易想到,一定把所有连通块都连在内部距离最大连通块的那个求出来的点上,一定是最优的。但是我们的最远距离计算方式需要谨慎,一般情况下是最大+次大+L,我只考虑了这种就只有22分。事实上最大连通块的直径同样可以成为答案,还有如果L很大的话次大和次次大之间也可构成最长距离,但是注意第三种情况只有是大于等于3个连通块的时候才有可能取到。

 //It is made by jump~
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#include <set>
using namespace std;
typedef long long LL;
#define RG register
const int MAXN = ;
const int MAXM = ;
const int inf = ;
int n,m,L,ecnt,s;
int first[MAXN],to[MAXM],next[MAXM],w[MAXM];
int f[MAXN][],father[MAXN],son[MAXN],pson[MAXN],belong[MAXN];
int ans1,ans2,ans3,ans; inline int getint()
{
RG int w=,q=; RG char c=getchar();
while((c<'' || c>'') && c!='-') c=getchar(); if(c=='-') q=,c=getchar();
while (c>='' && c<='') w=w*+c-'', c=getchar(); return q ? -w : w;
} inline void dfs(RG int x,RG int fa){
belong[x]=s; RG int now;
for(RG int i=first[x];i;i=next[i]) {
RG int v=to[i]; if(v==fa) continue;
dfs(v,x); now=f[v][]+w[i];
if(now>f[x][]) pson[x]=son[x],f[x][]=f[x][],f[x][]=now,son[x]=v; else if(now>f[x][]) f[x][]=now,pson[x]=v;
}
ans=max(f[x][]+f[x][],ans);
} inline void DFS(RG int x,RG int fa,RG int dis){
if(max(f[x][],dis)<ans) ans=max(f[x][],dis);
for(RG int i=first[x];i;i=next[i]) {
RG int v=to[i]; if(v==fa) continue;
if(v==son[x]) DFS(v,x,max(dis,f[x][])+w[i]);
else DFS(v,x,max(dis,f[x][])+w[i]);
}
} inline void work(){
n=getint(); m=getint(); L=getint(); RG int x,y,z;
for(RG int i=;i<=m;i++) {
x=getint()+; y=getint()+; z=getint();
next[++ecnt]=first[x]; first[x]=ecnt; to[ecnt]=y; w[ecnt]=z;
next[++ecnt]=first[y]; first[y]=ecnt; to[ecnt]=x; w[ecnt]=z;
}
for(RG int i=;i<=n;i++) if(!belong[i]) s=i,dfs(i,);
if(m==n-) { printf("%d",ans); return ; }
RG int cun=ans;
for(RG int i=;i<=n;i++)
if(belong[i]==i) {
ans=inf,DFS(i,,);
if(ans>ans1) ans3=ans2,ans2=ans1,ans1=ans;
else if(ans>ans2) ans3=ans2,ans2=ans;
else if(ans>ans3) ans3=ans;
}
ans=max(cun,ans1+ans2+L);
if(m<n-) ans=max(ans,ans2+ans3+L*);//必须要多于2块!
printf("%d",ans);
} int main()
{
work();
return ;
}

BZOJ3246 [Ioi2013]Dreaming的更多相关文章

  1. bzoj 3246 [Ioi2013]Dreaming 贪心

    [Ioi2013]Dreaming Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 638  Solved: 241[Submit][Status][Di ...

  2. 【IOI2013】【Bzoj3246】Dreaming

    http://www.lydsy.com/JudgeOnline/problem.php?id=3246 中文题面 天地之初,世界尚在遥远的梦想之中. Serpent(水蛇)生活的地方有N个水坑,编号 ...

  3. 【bzoj3246】 Ioi2013—Dreaming

    www.lydsy.com/JudgeOnline/problem.php?id=3246 (题目链接) 题意 给出一棵不完全的树,要求在树上连最少的边使得所有点联通,并且使得两点间最大距离最小. S ...

  4. [IOI2013]Dreaming

    link 一道非常类似的题目(link) 试题大意 给你一棵含有$n$个节点的有边权森林,问每次连边将会用$L$的代价,问你若此图通过加边成为树时的最小直径.$n \leq 5\times 10^5$ ...

  5. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  6. 读书笔记:《梦断代码Dreaming in Code》

    读书笔记:<梦断代码Dreaming in Code> 拿到<梦断代码>书后,一口气翻了一遍,然后又用了3天时间仔细读了一遍,也不禁掩卷长叹一声,做软件难.虽难,仍要继续走下去 ...

  7. BZOJ3246 IOI2013Dreaming

    如果将森林里每棵树都各自看做一个点,那么最后所连成的树应该是一颗菊花,否则将叶子节点父亲改为根不会更劣. 对于每个点所代表的树,其和根节点相连的点应该是到其他点距离最大值最小的点.这个点显然是直径的中 ...

  8. BZOJ3249 : [ioi2013]game

    线段树套Treap 外层的线段树需要动态开节点 内层Treap需要注意的是,相同y坐标的点不一定是同一个点,所以需要再次离散 空间$O(n\log n)$ 时间$O(n\log^2n)$ #inclu ...

  9. 《梦断代码Dreaming In Code》阅读笔记(三)

    最后这几章感觉上更多是从软件完成整体上来讲的.比如说技术.方法等. 在我看来,其实一个团队一直坚持一种好的.先进的方法是不可少的.如果一个优秀的团队刚愎自用,只随着成员们喜好发展,那不能长久.比如说, ...

随机推荐

  1. Win8/8.1 .NET3.5安装失败

    .NetFramework 作为开发人员,很多情况都需要.NetFramework,在Win7及之前的系统上直接双击 .NetFramework的安装包就可安装了. Win8/8.1无法安装.Net3 ...

  2. vmware12安装vmtools

    一. 1. 机器要开启支持BIOS的选项. 二. 1. 点击vmware 应用 vmware install 2. 虚拟机: tar  xvf vmtools-distb.tgr.gz 3. 虚拟机: ...

  3. angularjs: ng-select和ng-options

    angular.js有一个很强大的指令: ng-select 它可以帮助你通过数据模型来创建select元素.它很好的支持了select标签的语法,但是却有点坑. 假设有如下一段json数据: { & ...

  4. javascript中的后退和刷新

    <input type=button value=刷新 onclick="window.location.reload()"><input type=button ...

  5. 你会在C#的类库中添加web service引用吗?

    本文并不是什么高深的文章,只是VS2008应用中的一小部分,但小部分你不一定会,要不你试试: 本人对于分布式开发应用的并不多,这次正好有一个项目要应用web service,我的开发环境是vs2008 ...

  6. 3110 PHP常见问题

    1.中文显示 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /&g ...

  7. XXOOJL

    她的鞋子放在外面没拿进来很显眼,我们俩正抱在床上,刚做完什么也没穿,她也没擦.听到门外的脚步声.赶紧穿.她在我房间里没出声,但我父亲肯定看出来了.于是问我:母亲去哪了,然后他去找她. 太尴尬了,那晚我 ...

  8. DWZ (JUI) 教程 navTab 刷新分析

    navTab的刷新在doc文件里也有说明 首先 在form表单里指定好回调函数 * <form action="/user.do?method=save" onsubmit= ...

  9. VS2013中BOOST库的环境配置与使用

    &1 安装Boost 文件下载:链接:http://pan.baidu.com/s/1kUKaOFP 密码:auf2 解压之后放到你想安装的文件夹内,我的是在C:\Program Files\ ...

  10. Asp.net设计模式笔记之一:理解设计模式

    GOF设计模式著作中的23种设计模式可以分成三组:创建型(Creational),结构型(Structural),行为型(Behavioral).下面来做详细的剖析. 创建型 创建型模式处理对象构造和 ...