[Ioi2013]Dreaming

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 638  Solved: 241
[Submit][Status][Discuss]

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

 

题目大意

给定n个点m条边的森林,每条边有边权。要求用长度为L的边把它连成一棵树,且直径最小。

n≤500000

分析

首先对于森林中每一棵树,它只有一条路径可能会对答案有贡献。为了使答案尽量小,那就要使这个值尽量小。那么可以选择它的所有点中,到达其它点距离最大值最小的,去和其它树连接。然后这个点对答案的贡献就是这个距离。

那么会发现,这些数看成一个点之后,又会连成一棵树。 
由于这棵树的形态是任意的,肯定是选择一个点作为根,然后其它点和根直接连接最优。为了答案尽量小,又一定是把上面所述距离的最大值作为根。

那么对答案有贡献的就只有三种情况: 
1. 原来每棵树的直径 
2. 距离最大值+距离次大值+L 
3. 距离次大值+距离第3大值+2L

 #include<cstring>
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<queue>
#include<map> #define N 500007
#define M 1000007
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-;ch=getchar();}
while(isdigit(ch)){x=(x<<)+(x<<)+ch-'';ch=getchar();}
return x*f;
} int n,m,L;
int tot,h[N],e[M],nxt[M],w[M],fa[N],dis[N],D[N],ans,cnt,len[N];
bool v[N];
char c; void add(int x,int y,int d)
{
e[++tot]=y; nxt[tot]=h[x]; w[tot]=d; h[x]=tot;
} int main()
{
n=read(); m=read(); L=read();
while (m--)
{
int x=read()+,y=read()+,w=read();
add(x,y,w); add(y,x,w);
}
for (int i=;i<=n;i++)
if (!v[i])
{
D[tot=]=i;
for (int j=;j<=tot;j++)
{
int x=D[j];
v[x]=;
for (int k=h[x];k;k=nxt[k])
if (e[k]!=fa[x]) D[++tot]=e[k],dis[e[k]]=dis[x]+w[k],fa[e[k]]=x;
}
int r=D[tot];
for (int j=;j<tot;j++)
if (dis[D[j]]>dis[r]) r=D[j];
D[tot=]=r; dis[r]=; fa[r]=;
for (int j=;j<=tot;j++)
{
int x=D[j];
for (int k=h[x];k;k=nxt[k])
if (e[k]!=fa[x])
{
D[++tot]=e[k];
dis[e[k]]=dis[x]+w[k];
fa[e[k]]=x;
}
}
r=D[tot];
for (int j=;j<tot;j++)
if (dis[D[j]]>dis[r]) r=D[j];
ans=max(ans,dis[r]); len[++cnt]=dis[r];
for (int j=r;j>;j=fa[j]) len[cnt]=min(len[cnt],max(dis[j],dis[r]-dis[j]));
}
sort(len+,len+cnt+);
if (cnt==) ans=max(ans,len[]+len[]+L);
else if (cnt>) ans=max(ans,max(len[cnt]+len[cnt-]+L,len[cnt-]+len[cnt-]+L*));
printf("%d\n",ans);
}

bzoj 3246 [Ioi2013]Dreaming 贪心的更多相关文章

  1. BZOJ 1029 建筑抢修 贪心+堆

    又搞了一晚上OI,编了两道BZOJ和几道NOI题库,临走之前写两篇感想 noip越来越近了,韩大和clove爷已经开始停课虐我们了... 1029: [JSOI2007]建筑抢修 Time Limit ...

  2. [bzoj 2151]种树(贪心)

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2151 分析:原型是bzoj 1150(CTSC 2007) 首先DP无法下手,想到贪心.想到贪 ...

  3. BZOJ.5397.circular(随机化 贪心)

    BZOJ 感觉自己完全没做过环上选线段的问题(除了一个2-SAT),所以来具体写一写qwq. 基本完全抄自remoon的题解qwq... (下标从\(0\sim m-1\)) 拆环为链,对于原线段\( ...

  4. 【bzoj3246】 Ioi2013—Dreaming

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

  5. bzoj 5185 Lifeguards - 动态规划 - 贪心

    题目传送门 传送点I 传送点II 题目大意 给定$n$个区间,问恰好删去其中$k$个,剩下的区间的并的最大总长度. 显然被包含的区间一定不优.再加上被包含的区间对计数不友好.直接把它删掉. 注意到题目 ...

  6. BZOJ.3252.攻略(贪心 长链剖分/线段树)

    题目链接 贪心,每次选价值最大的一条到根的链.比较显然(不选白不选). 考虑如何维护这个过程.一个点的价值选了就没有了,而它只会影响它子树里的点,可以用DFS序+线段树修改.而求最大值也可以用线段树. ...

  7. BZOJ.4245.[ONTAK2015]OR-XOR(贪心)

    题目链接 从高到低位贪心,判断答案的该位能否为0. 求一个前缀和sum.对于最高位,答案的这一位可以为0当且仅当至少存在m个位置满足sum[i]在这一位上为0. 注意sum[n]这一位必须为0. 如果 ...

  8. BZOJ 3143 游走(贪心+期望+高斯消元)

    一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这条边的编号的分 ...

  9. [IOI2013]Dreaming

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

随机推荐

  1. lintcode: Missing String

    Missing String  描述: Given two strings, you have to find the missing string. Have you met this questi ...

  2. 《Spark 官方文档》在Mesos上运行Spark

    本文转自:http://ifeve.com/spark-mesos-spark/ 在Mesos上运行Spark Spark可以在由Apache Mesos 管理的硬件集群中运行. 在Mesos集群中使 ...

  3. [转]bashrc与profile区别

    作者:KornLee 2005-02-03 15:49:57 来自:Linux先生 /etc/profile:此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行.并从/etc/pro ...

  4. leetcode个人题解——#17 Letter Combinations of a Phone Number

    思路:用深搜遍历九宫格字符串,一开始做的时候发生了引用指向空地址的问题,后来发现是vector不能直接=赋值. class Solution { public: int len; ]={"a ...

  5. Python3 Tkinter-Checkbutton

    1.多选按钮创建 from tkinter import * root=Tk() Checkbutton(root,text='python').pack() root.mainloop() 2.绑定 ...

  6. js经典试题之数据类型

    js经典试题之数据类型 1:输出"B" + "a" + + "B" + "a"的值: 答案:BaNaNa. 分析:因为+ ...

  7. Thunder团队第一周 - Scrum会议2

    Scrum会议2 小组名称:Thunder 项目名称:待定 Scrum Master:李传康 工作照片: 参会成员: 王航:http://www.cnblogs.com/wangh013/ 李传康(M ...

  8. c#和.net区别

    .net 包含两大部分:.net framework类库和公共语言运行库(CLR) .net framework类库,就是微软工程师写好的各种功能类,例如math类. 公共语言运行库:1.与操作系统进 ...

  9. zabbix概念

    Zabbix是一个企业级的.开源的.分布式监控解决方案. Zabbix可以监控网络和服务的监控状况. Zabbix利用灵活的告警机制,允许用户对事件发送基于Email的告警. 这样可以保证快速的对问题 ...

  10. java 基础 --int 和Integer的区别

    感到脸红:int是整形 -128~127 Integer是正整型,你怎么会想到这样的回答,妈的,有脑子吗?!!! 1,int是基本数据类型,初始为0,Integer为封装类,初始为null ①无论如何 ...