bzoj 3246 [Ioi2013]Dreaming 贪心
[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
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
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 贪心的更多相关文章
- BZOJ 1029 建筑抢修 贪心+堆
又搞了一晚上OI,编了两道BZOJ和几道NOI题库,临走之前写两篇感想 noip越来越近了,韩大和clove爷已经开始停课虐我们了... 1029: [JSOI2007]建筑抢修 Time Limit ...
- [bzoj 2151]种树(贪心)
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2151 分析:原型是bzoj 1150(CTSC 2007) 首先DP无法下手,想到贪心.想到贪 ...
- BZOJ.5397.circular(随机化 贪心)
BZOJ 感觉自己完全没做过环上选线段的问题(除了一个2-SAT),所以来具体写一写qwq. 基本完全抄自remoon的题解qwq... (下标从\(0\sim m-1\)) 拆环为链,对于原线段\( ...
- 【bzoj3246】 Ioi2013—Dreaming
www.lydsy.com/JudgeOnline/problem.php?id=3246 (题目链接) 题意 给出一棵不完全的树,要求在树上连最少的边使得所有点联通,并且使得两点间最大距离最小. S ...
- bzoj 5185 Lifeguards - 动态规划 - 贪心
题目传送门 传送点I 传送点II 题目大意 给定$n$个区间,问恰好删去其中$k$个,剩下的区间的并的最大总长度. 显然被包含的区间一定不优.再加上被包含的区间对计数不友好.直接把它删掉. 注意到题目 ...
- BZOJ.3252.攻略(贪心 长链剖分/线段树)
题目链接 贪心,每次选价值最大的一条到根的链.比较显然(不选白不选). 考虑如何维护这个过程.一个点的价值选了就没有了,而它只会影响它子树里的点,可以用DFS序+线段树修改.而求最大值也可以用线段树. ...
- BZOJ.4245.[ONTAK2015]OR-XOR(贪心)
题目链接 从高到低位贪心,判断答案的该位能否为0. 求一个前缀和sum.对于最高位,答案的这一位可以为0当且仅当至少存在m个位置满足sum[i]在这一位上为0. 注意sum[n]这一位必须为0. 如果 ...
- BZOJ 3143 游走(贪心+期望+高斯消元)
一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这条边的编号的分 ...
- [IOI2013]Dreaming
link 一道非常类似的题目(link) 试题大意 给你一棵含有$n$个节点的有边权森林,问每次连边将会用$L$的代价,问你若此图通过加边成为树时的最小直径.$n \leq 5\times 10^5$ ...
随机推荐
- 142. O(1) Check Power of 2【LintCode by java】
Description Using O(1) time to check whether an integer n is a power of 2. Example For n=4, return t ...
- 感知机(perceptron)
- 关于智能指针类型shared_ptr的计数问题
一.关键 每个shared_ptr所指向的对象都有一个引用计数,它记录了有多少个shared_ptr指向自己 shared_ptr的析构函数:递减它所指向的对象的引用计数,如果引用计数变为0,就会销毁 ...
- Check the string
A has a string consisting of some number of lowercase English letters 'a'. He gives it to his friend ...
- Notes of the scrum meeting(12.9)
meeting time:14:00~17:00p.m.,December 9th,2013 meeting place:一号教学楼209 attendees: 顾育豪 ...
- QT界面绘制学习记录
1. MVC结构中,model必须作为类的成员变量存在,不可再函数内部申明.否则,会出现函数调用结束,model找不到的错误. 2.QcomboBox可设置为左边空白,右侧一小箭头的形式.代码:com ...
- button type=“submit”
写js遇到任何怪异的行为 一定要先看看是不是submit搞的鬼. 函数内部最后总是返回 return false; 也是一个好的习惯
- 《剑指offer》---顺时针打印矩阵
本文算法使用python3实现 1. 问题1 1.1 题目描述: 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 ...
- 读写INI文件操作类
详情介绍:http://zh.wikipedia.org/wiki/INI%E6%96%87%E4%BB%B6 示例: 下面是一个虚拟的程序,其INI文件有两个小节,前面的小节是用来设置拥有者的信息, ...
- 3ds Max学习日记(五)
把实验室要用的小工具做了出来后,忙里偷闲,把第四章没看完的视频看完了.修改器(modifier)什么的还是挺好玩的. FFD,车削,倒角,倒角剖面,对称,挤出,晶格,扭曲,融化,弯曲,网格平滑 ...