高中OJ3516. 【NOIP2013模拟11.6A组】摧毁巴士站
来源:互联网 发布:linux 2017年重大漏洞 编辑:程序博客网 时间:2024/04/29 10:26
30分:
枚举要摧毁的车站,判断符不符合要求。
100分:
很显然,2^48会超时。
解决办法是有选择性的进行删点。基本的思路就是,一条长度不超过k的最短路径上的点,至少有一个是要被删掉的(至于删除哪个好,可以枚举尝试),删掉一个点后再重新求最短路,如果新求出的最短路径长度仍然不超过k,那么就在新的最短路径上再找出一个点删掉,然后再求最短路径……直到求出的最短路径长度超过k,那么就找到了一个解。但这个解未必是最优的,所以要用递归的方法搜索多组解,以确保能搜到最优解。具体步骤如下。
递归进行下列操作:
1. 寻找起点到终点的最短路径,如果最短路径长度超过k,则表示已找到一种删点方案。记录该方案下的删点数目,回溯再找出下一种方案;否则进入下一步。
2. 枚举最短路径中的除1号点和n号点外的某一个点,将其删除。
3. 回到1递归继续搜索。
这样的搜索顺序使得枚举的点的数量得到控制。搜索的每一层会从L-2个点中选择一个进行删除,L是当前找到的最短路径的长度。如果当前找到的最短路径很长,虽然在这一层我们需要枚举很多个点进行删除,但也说明起点到终点的距离已经很长了,我们离答案已经很接近了。一般来说,在50个点的图中,答案应该不超过20。那么L<20。并且L比较大的情况只会出现在搜索的最后几层。这么想来,这个搜索的时间复杂度是可以接受的。
所以我们可以每次进行一次最短路,每次删掉最短路上的一个点,然后继续回溯。
直到最短路的长度大于k,就记录答案。
代码
var a:array[1..4000,1..2] of longint; b:array[1..50] of longint; c:array[1..51] of longint; bz:array[1..50] of boolean; d:array[1..10000,1..2] of longint; f:array[1..50] of longint; bz2:array[1..50,1..50] of boolean; xl:array[1..50] of longint; n,m,s,i,j,ans,h,t,x,y,tot:longint;function pd:longint;var i,j,k,l:longint;begin pd:=0; h:=0; t:=1; fillchar(f,sizeof(f),10); f[1]:=0; d[1,1]:=1; d[1,2]:=0; while h<t do begin inc(h); j:=d[h,1]; for i:=c[j] to c[j+1]-1 do if (bz[a[i,2]]=false) and (f[j]+1<f[a[i,2]]) then begin k:=a[i,2]; f[k]:=f[j]+1; inc(t); d[t,1]:=k; d[t,2]:=h; if k=n then begin pd:=f[k]; tot:=0; l:=h; while d[l,1]<>1 do begin inc(tot); xl[tot]:=d[l,1]; l:=d[l,2]; end; exit; end; end; end; pd:=maxlongint;end;procedure dg(t:longint);var dl:array[1..50] of longint; i,j:longint;begin if t-1>=ans then exit; if pd>s then begin if ans>t-1 then ans:=t-1; exit; end; dl:=xl; j:=tot; for i:=1 to j do if bz[dl[i]]=false then begin bz[dl[i]]:=true; dg(t+1); bz[dl[i]]:=false; end;end;begin assign(Input,'bus.in'); reset(Input); assign(Output,'bus.out'); rewrite(Output); readln(n,m,s); for i:=1 to m do begin readln(x,y); bz2[x,y]:=true; end; m:=0; for i:=1 to n do for j:=1 to n do if bz2[i,j] then begin inc(m); a[m,1]:=i; a[m,2]:=j; inc(b[i]); end; c[1]:=1; for i:=2 to n+1 do c[i]:=c[i-1]+b[i-1]; ans:=maxlongint; dg(1); writeln(ans); close(Input); close(Output);end.
2 0
- 高中OJ3516. 【NOIP2013模拟11.6A组】摧毁巴士站
- 高中3523. 【NOIP2013模拟11.7A组】JIH的玩偶
- 高中OJ3505. 【NOIP2013模拟11.4A组】积木(brick)
- 高中OJ3514. 【NOIP2013模拟11.6B组】最小比例
- 高中OJ3515. 【NOIP2013模拟11.6B组】软件公司
- 高中OJ3517. 【NOIP2013模拟11.6B组】空间航行
- 2017.2.11【初中部 GDKOI】模拟赛B组 摧毁巴士站(bus) 题解
- 2017.2.11【初中部 GDKOI】模拟赛B组 T4:摧毁巴士站
- 高中OJ3511. 【NOIP2013模拟11.5A组】cza的蛋糕(cake)
- 高中OJ3502. 【NOIP2013模拟11.4B组】方格游戏(game)
- 高中OJ3503. 【NOIP2013模拟11.4B组】粉刷(paint)
- 高中OJ3504. 【NOIP2013模拟11.4B组】运算符(calc)
- jzoj. 3518. 【NOIP2013模拟11.6A组】进化序列(evolve)
- JZOJsenior3518.【NOIP2013模拟11.6A组】进化序列
- JZOJ 3518. 【NOIP2013模拟11.6A组】进化序列(evolve)
- jzoj3518【NOIP2013模拟11.6A组】进化序列
- 【NOIP2013模拟11.6A组】灵能矩阵(pylon)
- 【NOIP2013模拟11.5A组】游戏节目
- sizeof用法介绍
- 开通博客
- 二叉树经典面试题6~二叉树中和为某一值的路径
- git设置账户名和邮箱
- maven初次使用
- 高中OJ3516. 【NOIP2013模拟11.6A组】摧毁巴士站
- JavaSe总结-11-开发工具 & API常用对象(1)
- 历届试题 地宫取宝
- 洛谷 1162——填涂颜色(广度优先搜索)
- 使用Nginx+Lua(OpenResty)开发高性能Web应用
- 2.11
- 关于重放攻击的知识点
- 学习笔记之-51单片机最小系统搭建
- Java 基础(2)----基本语法一