題目大意:
在乙個有向圖中找出2點之間的最短路,並且路徑上的所有點的出邊所指向的點都直接或間接與終點連通。
題解:
spfa+佇列+dfs:
1.從終點方向搜,把終點能到的點標記可到達。
2.把終點能到達的點的出邊判斷,如果出邊未被標記則狀態更新為不可到達。
3.做spfa,若t[i]可以到達就做,不然不做。
var
d,s,t,next,list:array [0..200001] of longint;
dis:array [0..10001] of longint;
f,v,k:array [0..10001] of boolean;
i,j,n,m,p,q:longint;
procedure
dfs(dep:longint);
var i:longint;
begin
i:=list[dep];
f[dep]:=true;
while i>0
dobegin
if f[s[i]]=false
then dfs(s[i]);
i:=next[i];
end;
end;
function
flag
(x:longint):boolean;
var i:longint;
begin
i:=list[x];
if f[x]=false
then
exit(false);
while i>0
dobegin
if f[t[i]]=false
then
exit(false);
i:=next[i];
end;
exit(true);
end;
procedure
spfa;
var head,tail,i:longint;
begin
head:=0;
tail:=1;
dis[p]:=0;
v[p]:=true;
d[1]:=p;
while headdo
begin
inc(head);
i:=list[d[head]];
while i>0
dobegin
if (dis[s[i]]+1
and (k[t[i]])
then
begin
dis[t[i]]:=dis[s[i]]+1;
if v[t[i]]=false
then
begin
v[t[i]]:=true;
inc(tail);
d[tail]:=t[i];
end;
end;
i:=next[i];
end;
v[d[head]]:=false;
end;
end;
begin
readln(n,m);
for i:=1
to m do
begin
readln(s[i],t[i]);
next[i]:=list[t[i]];
list[t[i]]:=i;
end;
readln(p,q);
dfs(q);
for i:=1
to n do
begin
v[i]:=false;
dis[i]:=maxlongint;
list[i]:=0;
k[i]:=false;
end;
for i:=1
to m do
begin
next[i]:=list[s[i]];
list[s[i]]:=i;
end;
for i:=1
to n do
if f[i] then k[i]:=flag(i);
spfa;
if dis[q]<>maxlongint then writeln(dis[q])
else writeln('-1');
end.
洛谷P2296 尋找道路
在有向圖g 中,每條邊的長度均為1 現給定起點和終點,請你在圖中找一條從起點到終點的路徑,該路徑滿足以下條件 1 路徑上的所有點的出邊所指向的點都直接或間接與終點連通。2 在滿足條件1 的情況下使路徑最短。注意 圖g 中可能存在重邊和自環,題目保證終點沒有出邊。請你輸出符合條件的路徑的長度。輸入格式...
洛谷 P2296 尋找道路
題目描述 在有向圖g 中,每條邊的長度均為1 現給定起點和終點,請你在圖中找一條從起點到終點的路徑,該路徑滿足以下條件 1 路徑上的所有點的出邊所指向的點都直接或間接與終點連通。2 在滿足條件1 的情況下使路徑最短。注意 圖g 中可能存在重邊和自環,題目保證終點沒有出邊。請你輸出符合條件的路徑的長度...
洛谷 P2296 尋找道路
題目描述 在有向圖g 中,每條邊的長度均為1 現給定起點和終點,請你在圖中找一條從起點到終點的路徑,該路徑滿足以下條件 1 路徑上的所有點的出邊所指向的點都直接或間接與終點連通。2 在滿足條件1 的情況下使路徑最短。注意 圖g 中可能存在重邊和自環,題目保證終點沒有出邊。請你輸出符合條件的路徑的長度...