消防(mindist)
来源:互联网 发布:最火淘宝浏览单app软件 编辑:程序博客网 时间:2024/04/27 19:58
消防(mindist)
【问题描述】
某个国家有n 个城市,这n 个城市中任意两个都连通且有唯一一条路径,每
条连通两个城市的道路的长度为zi(zi<=1000)。
这个国家的人对火焰有超越宇宙的热情,所以这个国家最兴旺的行业是消防
业。由于政府对国民的热情忍无可忍(大量的消防经费开销)可是却又无可奈何
(总统竞选的国民支持率),所以只能想尽方法提高消防能力。
现在这个国家的经费足以在一条边长度和不超过s 的路径(两端都是城市)
上建立消防枢纽,为了尽量提高枢纽的利用率,要求其他所有城市到这条路径的
距离的最大值最小。
你受命监管这个项目,你当然需要知道应该把枢纽建立在什么位置上。
【输入格式】
输入包含n 行:
第1 行,两个正整数n 和s,中间用一个空格隔开。其中n 为城市的个数,
s 为路径长度的上界。设结点编号以此为1,2,……,n。
从第2 行到第n 行,每行给出3 个用空格隔开的正整数,依次表示每一条边的
两个端点编号和长度。例如,“2 4 7”表示连接结点2 与4 的边的长度为7。
【输出格式】
输出包含一个非负整数,即所有城市到选择的路径的最大值,当然这个最大
值必须是所有方案中最小的。
【问题描述】
某个国家有n 个城市,这n 个城市中任意两个都连通且有唯一一条路径,每
条连通两个城市的道路的长度为zi(zi<=1000)。
这个国家的人对火焰有超越宇宙的热情,所以这个国家最兴旺的行业是消防
业。由于政府对国民的热情忍无可忍(大量的消防经费开销)可是却又无可奈何
(总统竞选的国民支持率),所以只能想尽方法提高消防能力。
现在这个国家的经费足以在一条边长度和不超过s 的路径(两端都是城市)
上建立消防枢纽,为了尽量提高枢纽的利用率,要求其他所有城市到这条路径的
距离的最大值最小。
你受命监管这个项目,你当然需要知道应该把枢纽建立在什么位置上。
【输入格式】
输入包含n 行:
第1 行,两个正整数n 和s,中间用一个空格隔开。其中n 为城市的个数,
s 为路径长度的上界。设结点编号以此为1,2,……,n。
从第2 行到第n 行,每行给出3 个用空格隔开的正整数,依次表示每一条边的
两个端点编号和长度。例如,“2 4 7”表示连接结点2 与4 的边的长度为7。
【输出格式】
输出包含一个非负整数,即所有城市到选择的路径的最大值,当然这个最大
值必须是所有方案中最小的。
【样例输入1】
5 2
1 2 5
2 3 2
2 4 4
2 5 3
【样例输出1】
5
【样例输入2】
8 6
1 3 2
2 3 2
3 4 6
4 5 3
4 6 4
4 7 2
7 8 3
【样例输出2】
5
【数据规模和约定】
对于20%的数据,n<=300。
对于50%的数据,n<=3000。
对于100%的数据,n<=300000,边长小等于1000。
可以证明,建立枢纽的路必然在树的直径(即树的最长链)上
这个问题明显具有单调性,如果3可以,那4也可以
所以可以二分答案,问题就变为已知一个答案,如何验证是否可行
首先预处理一下直径上的点的不在直径上的最长链,其中最长的即为答案下界
然后贪心处理即可,从链的底部出发向上,在不超过答案的情况下就不把边删除,之后能删除多少边就删除多少边,删除完判断合法不合法即可
program mindist;var mid,l,r,bot,top,max,tot,n,s,i,j,k,u,v,c:longint; val,oth,father,dis,root:array [0..300001] of longint; next,cost,point:array [0..600001] of longint; line:array [0..300001] of boolean;procedure connect (u,v,c:longint);inline;begin inc(tot); point[tot]:=v; cost[tot]:=c; next[tot]:=root[u]; root[u]:=tot;end;procedure search (now:longint);var i:longint;begin if dis[now]>dis[max] then max:=now; i:=root[now]; while i<>0 do begin if point[i]<>father[now] then begin dis[point[i]]:=dis[now]+cost[i]; father[point[i]]:=now; val[point[i]]:=cost[i]; search(point[i]); end; i:=next[i]; end;end;procedure dfs (now:longint);var i:longint;begin i:=root[now]; while i<>0 do begin if point[i]<>father[now] then begin dfs(point[i]); if not line[point[i]] then if oth[point[i]]+cost[i]>oth[now] then oth[now]:=oth[point[i]]+cost[i]; end; i:=next[i]; end; if oth[now]>max then max:=oth[now];end;function ok (ans:longint):boolean;var i,k,now:longint;begin i:=bot; while (i<>top)and(dis[bot]-dis[father[i]]<=ans) do i:=father[i]; now:=0; while i<>top do begin if now+val[i]>s then break; now:=now+val[i]; i:=father[i]; end; if dis[i]>ans then exit(false) else exit(true);end;begin assign(input,'mindist.in'); reset(input); assign(output,'mindist.out'); rewrite(output); read(n,s); for i:=1 to n-1 do begin read(u,v,c); connect(u,v,c); connect(v,u,c); end; fillchar(father,sizeof(father),0); fillchar(dis,sizeof(dis),0); max:=1; search(1); top:=max; fillchar(father,sizeof(father),0); fillchar(dis,sizeof(dis),0); search(top); bot:=max; fillchar(line,sizeof(line),false); i:=bot; repeat line[i]:=true; i:=father[i]; until i=0; max:=0; dfs(top); l:=max; r:=300000; while l<>r do begin mid:=(l+r) div 2; if ok(mid) then r:=mid else l:=mid+1; end; writeln(l); close(input); close(output);end.
- 消防(mindist)
- 消防文摘
- 消防按钮
- 消防演习
- 消防站
- [SDOI2011]消防
- 消防知识讲座笔记
- 消防信息安全
- 消防通信指挥系统
- 消防监控方案(ARM)
- 消防监控GIS应用
- 关注消防 和谐校园
- 消防炮日志
- 家中必备消防装备
- 消防可燃气体探测器安装验收
- 上海市消防专家培训
- 消防应急指挥系统
- 2282: [Sdoi2011]消防
- 第十一周作业
- 2011年10月28日
- Linux题目
- 新浪分享网址(复制这段代码,粘贴到你的网站上任意位置。)
- 第十一周作业2
- 消防(mindist)
- 人类已经无法阻止理工科宅男了~~~(Gnuplot 和 Matplotlib使用小节)
- 第十周作业 1
- android permission 中英文对比大全
- 第二周报告三
- Linux内核访问外设I/O资源的方式
- 使用crond 在linux中定时执行任务 (狗一样~)
- 第十二周作业(一)
- Android Processes and Threads学习笔记