2017.2.11【初中部 GDKOI】模拟赛B组 T4:摧毁巴士站

【NOIP2013模拟11.6A组】摧毁巴士站(bus)
Description

Gabiluso是最伟大的间谍之一。现在,他试图完成一个“不可能完成”的使命――减缓Colugu的军队到达机场的时间。Colugu有n个公共汽车站和m条道路。每条道路直接连接两个巴士站,所有的道路都是单向的。为了保持空气洁净,政府禁止所有军用车辆,因此,军队必须乘搭巴士去机场。两个巴士站之间,可能有超过一条道路。如果一个公共汽车站被破坏时,所有连接该站的道路将无法运作。Gabiluso需要做的是摧毁了一些公共汽车站,使军队无法在K分钟内到达机场。一辆公交车通过一条道路,都是一分钟。所有巴士站的编号从1到n。1号巴士站是在军营,第n号站是机场。军队始终从第一站出发。第一站和第n站不能被破坏,这里有大量的防御力量。当然也没有从第一站到第n站的道路。

请帮助Gabiluso来计算能完成使命所需摧毁的最低数目的巴士站。

Input

第一行包含三个整数n,m,k

接下来m行,每行2个整数s和f,表示从站s到站f有一条路。

Output

输出最少需要摧毁的巴士站数目。

Sample Input

5 7 3

1 3

3 4

4 5

1 2

2 5

1 4

4 5

Sample Output

2

题解:本题还是十分有含金量的题目,用爆搜会时超,加最短路,才AC(听说可以用网络流)具体做法就是——
可以递归摧毁哪个点,然后最短路判断。但是有些点,可能经过他的路径,长度都是大于k的,那么这些点就不必要进行递归。于是,我们每次找一次最短路,看看从1~n的最短路分别经过了哪几个点。因为这里面的点都是在不符合条件的最短路里,所以我们递归那些经过的点删或者不删,直到最短路符合k的条件为止,去一个删的数目最少的为答案即可。 存最短路径是一条怎样的路,可以用s[x]表示更新x这个点,最后是哪个点更新的,即可。

标程:

var
        ans,head,tail,n,m,i,j,k,l,u,v,x,y:longint;
        t,dist,zt:array[0..101]of longint;
        map:array[0..101,0..101]of longint;
        bz,bz1:array[0..101]of boolean;
procedure spfa;
begin
        fillchar(bz1,sizeof(bz1),false);
        fillchar(dist,sizeof(dist),127);
        fillchar(zt,sizeof(zt),0);
        fillchar(t,sizeof(t),0);
        dist[1]:=0;
        t[1]:=1;
        head:=0;
        tail:=1;
        bz1[1]:=true;
        repeat
                inc(head);
                u:=t[head];
                bz1[u]:=false;
                for v:=1 to n do
                begin
                        if(bz[v])and(map[u,v]>0)and(dist[v]>dist[u]+map[u,v])then
                        begin
                                dist[v]:=dist[u]+map[u,v];
                                zt[v]:=u;
                                if bz1[v]=false then
                                begin
                                        inc(tail);
                                        t[tail]:=v;
                                        bz1[v]:=true;
                                end;
                        end;
                end;
        until head>=tail;

end;

procedure dg(dep:longint);
var
        i,j,l:longint;
        q:array[0..101] of longint;
begin
        if dep>ans then exit;
        spfa;
        if dist[n]>k then
        begin
                if dep<ans then ans:=dep;
                exit;
        end
        else
        begin
                l:=dist[n]+1;
                q[l]:=n;
                while zt[q[l]]>0 do
                begin
                        dec(l);
                        q[l]:=zt[q[l+1]];
                end;
                for i:=2 to dist[n] do
                begin
                        bz[q[i]]:=false;
                        dg(dep+1);
                        bz[q[i]]:=true;
                end;
        end;
end;

begin
        assign(input,'bus.in');reset(input);
        assign(output,'bus.out');rewrite(output);
        fillchar(bz,sizeof(bz),true);
        readln(n,m,k);
        for i:=1 to m do
        begin
                readln(x,y);
                if map[x,y]=0 then
                inc(map[x,y]);
        end;
        ans:=maxlongint;
        dg(0);
        writeln(ans);
        close(input);close(output);
end.


posted @ 2017-02-11 21:50  RainbowCrown  阅读(246)  评论(0编辑  收藏  举报