洛谷 P2296 寻找道路

11 篇文章 0 订阅
9 篇文章 0 订阅

题目

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

1 .路径上的所有点的出边所指向的点都直接或间接与终点连通。

2 .在满足条件1 的情况下使路径最短。

注意:图G 中可能存在重边和自环,题目保证终点没有出边。

请你输出符合条件的路径的长度。

题解

第一眼看题目——-懵逼1s
然后还是不会
看了一波洛谷题解,好像是:
先从终点出发bfs处理不能到终点的点,把直接和间接通向不与终点相连的点标记
然后spfa跑一遍
时间复杂度O(nm)

嗯,好像很简单
然而并不是这样。打了175行的代码,错了n次,超时n次。发生了什么?

再仔细翻一遍洛谷题解,“并不需要BFS。读题后发现,不能走的点为除终点以外出度为0的点,以及与这些点直接相连的点。那就删了就好了。。。。”
一语点醒梦中人!
然后不停的删原代码,最后78行过了
发生了什么?

时间复杂度O(nm)

代码

type
  rec=record
        x,y,ne:longint;
      end;
var
  n,m,s,t,i,j,c:longint;
  d:array[0..10000]of longint;
  f:array[1..200000]of rec;
  b,e:array[1..10000]of boolean;
  ls:array[1..10000]of longint;
  v,state:array[1..10000]of longint;

procedure spfa;
var
  i,j,l,x,y,h,ta:longint;
begin
  fillchar(state,sizeof(state),0);
  state[1]:=t;v[t]:=1;d[t]:=0;b[t]:=true;b[s]:=true;
  h:=0;ta:=1;
  while h<ta do
    begin
      inc(h);
      l:=ls[state[h]];
      while l>0 do
        begin
          x:=f[l].x;y:=f[l].y;
          if b[y] and(d[x]+1<d[y])then
            begin
              d[y]:=d[x]+1;
              if v[y]=0 then
                begin
                  inc(ta);
                  state[ta]:=y;
                  v[y]:=1;
                end;
            end;
          l:=f[l].ne;
        end;
    end;
end;

procedure bfs(k:longint);
var
  l,y:longint;
begin
  l:=ls[k];
  while l>0 do
    begin
      y:=f[l].y;
      e[y]:=false;
      l:=f[l].ne;
    end;
end;

begin
  readln(n,m);
  j:=m;
  fillchar(d,sizeof(d),$7f);
  fillchar(b,sizeof(b),false);
  for i:=1 to j do
    begin
      readln(s,t);
      inc(c);
      f[c].x:=t;f[c].y:=s;f[c].ne:=ls[t];
      ls[t]:=c;
      b[s]:=true;
    end;
  readln(s,t);
  b[t]:=true;
  e:=b;
  for i:=1 to n do
    if not b[i] then
      bfs(i);
  b:=e;
  spfa;
  if d[s]=d[0] then writeln('-1') else writeln(d[s]);
end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值