• 寻找道路(codevs 3731)题解


    【问题描述】

    在有向图 G 中,每条边的长度均为 1,现给定起点和终点,请你在图中找一条从起点到 终点的路径,该路径满足以下条件:

    1. 路径上的所有点的出边所指向的点都直接或间接与终点连通。
    2. 在满足条件 1 的情况下使路径最短。

    注意:图 G 中可能存在重边和自环,题目保证终点没有出边。 请你输出符合条件的路径的长度。

    【样例输入1】

        3 2
        1 2
        2 1
        1 3

    【样例输出1】

        -1

    【样例输入2】

        6 6
        1 2
        1 3
        2 6
        2 5
        4 5
        3 4
        1 5

    【样例输出2】

        3

    【解题思路】

         又是要用邻接表的题,我又华丽丽地用了邻接矩阵,加上当初SB一般的用广搜+深搜去搜能到的顶点,用了两个布尔型数组,求最短路的时候用了floyed(其实这个都没什么了,之前的就足够MLE了……),再次爆零……

        OK,吐槽完之后,继续来说正解。

        邻接表,不多说了,以后看到需要存储边的题目都去用邻接表!管你有没有权。由于这题需要判断能否到达终点,于是我们需要反向存储。一遍DFS找到所有不能直接或间接到达的点,将它们的所有的入边的点全部删掉,如果起点无法到达的话,就输出-1,否则就是求最短路了。

    【代码实现】

     1 type rec=record
     2      c,next:longint;
     3 end;
     4 var e:array[1..200000] of rec;
     5     g:array[1..10000] of longint;
     6     efree,i,n,m,k,x,y,s,t,j:longint;
     7     a:array[1..10000] of longint;
     8     f,flag:array[1..10000] of boolean;
     9 procedure add;
    10 begin
    11  e[efree].c:=x;
    12  e[efree].next:=g[y];
    13  g[y]:=efree;
    14  inc(efree);
    15 end;
    16 procedure dfs(x:longint);
    17 var j:longint;
    18 begin
    19  f[x]:=true;
    20  j:=g[x];
    21  while j<>0 do
    22   begin
    23    if not f[e[j].c] then
    24     dfs(e[j].c);
    25    j:=e[j].next;
    26   end;
    27 end;
    28 procedure dijkstra;
    29 var i,j,min,pos:longint;
    30 begin
    31  fillchar(f,sizeof(f),false);
    32  f[t]:=true;
    33  a[t]:=0;
    34  for j:=1 to n do
    35   begin
    36    pos:=t;
    37    min:=maxint;
    38    for i:=1 to n do
    39     if (not f[i])and(a[i]<min)and(flag[i]) then
    40      begin
    41       pos:=i;
    42       min:=a[i];
    43      end;
    44    f[pos]:=true;
    45    i:=g[pos];
    46    while i<>0 do
    47     begin
    48      if flag[e[i].c] then
    49       if a[e[i].c]>a[pos]+1 then
    50        a[e[i].c]:=a[pos]+1;
    51      i:=e[i].next;
    52     end;
    53   end;
    54 end;
    55 begin
    56  readln(n,m);
    57  efree:=1;
    58  for i:=1 to m do
    59   begin
    60    readln(x,y);
    61    add;
    62   end;
    63  readln(s,t);
    64  dfs(t);
    65  flag:=f;
    66  for i:=1 to n do
    67   if not f[i] then
    68    begin
    69     j:=g[i];
    70     while j<>0 do
    71      begin
    72       flag[e[j].c]:=false;
    73       j:=e[j].next;
    74      end;
    75    end;
    76  if not flag[s] then
    77   begin
    78    writeln(-1);
    79    halt;
    80   end;
    81  for i:=1 to n do
    82   a[i]:=maxint;
    83  dijkstra;
    84  writeln(a[s]);
    85 end.
  • 相关阅读:
    Java byte类型转换成int类型时需要 & 0XFF的原因
    Java 原码 反码 补码
    HTTP 响应头信息(Http Response Header) Content-Length 和 Transfer-Encoding
    [No0000E6]C# 判断与循环
    [No0000E5]C# 运算符
    [No0000E3]C# 数据类型
    [No0000E2]Vmware虚拟机安装 苹果系统 mac OS 10.12
    [No0000E1]C# 关键字
    [No0000E0]批量打开当前路径下的文件
    [No0000DF]C# ZipFileHelper ZIP类型操作,压缩解压 ZIP 类封装
  • 原文地址:https://www.cnblogs.com/PengBoLiuXu/p/4536158.html
Copyright © 2020-2023  润新知