尋找道路(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.

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章