最短路(path.c/cpp)
[问题描述]
给定一个包含N个点,M条边的无向图,每条边的边权均为1。
再给定K个三元组(A,B,C),表示从A点走到B点后不能往C点走。注意三元组是有序的,如可以从B点走到A点再走到C。
现在你要在K个三元组的限制下,找出1号点到N号点的最短路径,并输出任意一条合法路径,会有Check检查你的输出。
[输入格式]
输入文件第一行有三个数N,M,K,意义如题目所述。
接下来M行每行两个数A,B,表示A,B间有一条边。
再下面K行,每行三个数(A,B,C)描述一个三元组。
[输出格式]
输出文件共两行数,第一行一个数S表示最短路径长度。
第二行S+1个数,表示从1到N所经过的节点。
[样例输入]
4 4 2
1 2
2 3
3 4
1 3
1 2 3
1 3 4
[样例输出]
4
1 3 2 3 4
[数据范围]
对于40%的数据满足N≤10,M≤20,K≤5。
对于100%的数据满足N≤3000,M≤20000,K≤100000。
===========================================
================
type
pnode=^node;
node=record
x:longint;
next:pnode;
end;
tnode=record
l,x:longint;
end;
pnode1=^node1;
node1=record
x:longint;
next:pnode1;
end;
var
n,m,k:longint;
map:array[0..3000]of pnode;
f_bo:array[0..3000,0..3000]of pnode1;
dist:array[0..3000,0..3000]of longint;
dist_l:array[0..3000,0..3000]of longint;
v:array[0..3000,0..3000]of boolean;
queue:array[1..100000]of tnode;
procedure init;
begin
assign(input,'path.in');
assign(output,'path.out');
reset(input); rewrite(output);
end;
procedure terminate;
begin
close(input); close(output);
halt;
end;
procedure insert(a,b:longint);
var
p:pnode;
begin
new(p);
p^.x:=b;
p^.next:=map[a];
map[a]:=p;
end;
procedure print(a,b:longint);
begin
if dist_l[a,b]<>0 then print(dist_l[a,b],a);
write(a,' ');
end;
function can(a,b,c:longint):boolean;
var
p:pnode1;
begin
p:=f_bo[a,b];
can:=true;
while p<>nil do
begin
if p^.x=c then exit(false);
p:=p^.next;
end;
end;
procedure spfa;
var
i:longint;
l,r:longint;
x,last:longint;
p:pnode;
ans,ansi:longint;
begin
fillchar(dist,sizeof(dist),$7);
fillchar(v,sizeof(v),true);
l:=0; r:=1;
queue[1].x:=1;
queue[1].l:=0;
dist[0,1]:=0; dist_l[0,1]:=0;
v[0,1]:=false;
repeat
inc(l);
x:=queue[l].x;
last:=queue[l].l;
p:=map[x];
while p<>nil do
begin
if can(last,x,p^.x)and(dist[last,x]+1<dist[x,p^.x]) then
begin
dist[x,p^.x]:=dist[last,x]+1;
dist_l[x,p^.x]:=last;
if v[x,p^.x] then
begin
v[x,p^.x]:=false;
inc(r);
queue[r].l:=x;
queue[r].x:=p^.x;
end;
end;
p:=p^.next;
end;
v[last,x]:=true;
until l>r;
ans:=maxlongint;
for i:=1 to n do
if dist[i,n]<ans then begin ans:=dist[i,n]; ansi:=i; end;
writeln(ans);
print(ansi,n);
writeln(n);
end;
procedure insert1(a,b,c:longint);
var
p:pnode1;
begin
new(p);
p^.x:=c;
p^.next:=f_bo[a,b];
f_bo[a,b]:=p;
end;
procedure main;
var
i,j:longint;
a,b,c:longint;
begin
readln(n,m,k);
fillchar(f_bo,sizeof(f_bo),0);
for i:=1 to n do
for j:=1 to n do f_bo[i,j]:=nil;
for i:=1 to n do map[i]:=nil;
for i:=1 to m do begin readln(a,b); insert(a,b); insert(b,a); end;
for i:=1 to k do begin readln(a,b,c); insert1(a,b,c); end;
spfa;
end;
begin
init;
main;
terminate;
end.