JZOJ8.16(C组)最短路

题目:

给定一个包含N个点,M条边的无向图,每条边的边权均为1。
再给定K个三元组(A,B,C),表示从A点走到B点后不能往C点走(即路径中不能出现连续三个点为ABC)。注意三元组是有序的,如可以从B点走到A点再走到C点。
现在你要在K个三元组的限制下,找出1号点到N号点的最短路径,并输出任意一条合法路径,会有Check检查你的输出。

分析:

bfs+标记,判定好K个三元组的情况即可。


附上代码:

const
  maxn=2000;

var
  data:array[0..maxn,1..2] of longint;
  map,temp:array[0..maxn,0..maxn] of longint;
  father:array[0..maxn] of longint;
  n,m,k,num:longint;

procedure work(x,y:longint);
begin
  inc(map[x,0]);
  map[x,map[x,0]]:=y;
end;

procedure init;
var
  x,y,i:longint;
begin
  readln(n,m,k);
  for i:=1 to m do
    begin
      readln(x,y);
      work(x,y);
      work(y,x);
    end;
  for i:=1 to k do
    begin
      readln(x,y,num);
      temp[x,y]:=num;
    end;
  if n=1 then
    begin
      writeln(0);
      writeln(1);
      halt;
    end;
end;

procedure print(tail:longint);
begin
  writeln(data[tail,2]);
  halt;
end;

procedure bfs;
var
  head,tail,i:longint;
begin
  head:=1;tail:=1;
  data[head,1]:=1;data[head,2]:=0;father[head]:=0;
  while head<=tail do
    begin
      num:=data[head,1];
      for i:=1 to map[num,0] do
        if temp[data[father[head],1],num]<>map[num,i] then
          begin
            inc(tail);
            father[tail]:=head;
            data[tail,1]:=map[num,i];
            data[tail,2]:=data[head,2]+1;
            if data[tail,1]=n then
              print(tail);
          end;
      inc(head);
    end;
end;

begin
  init;
  bfs;
end.

你可能感兴趣的:(神奇的中山纪中)