【CF721C】Journey(拓扑排序,最短路,DP)

题意:给一个无环的图,问用不超过T的时间从1到n最多可以经过多少个点。要求输出一条路径。

思路:因为无环,可以用DP做。不过因为时间最短的原因要拓扑排序后再DP,目测由底向上的更新也是可以的。

         

 1 const oo=1100000000;
 2 var dp,f:array[1..5000,1..5000]of longint;
 3     head,vet,next,len,flag,d,q,b:array[1..11000]of longint;
 4     n,m,tot,i,j,time,k,x,y,z,ans:longint;
 5 
 6 procedure add(a,b,c:longint);
 7 begin
 8  inc(tot);
 9  next[tot]:=head[a];
10  vet[tot]:=b;
11  len[tot]:=c;
12  head[a]:=tot;
13 end;
14 
15 procedure print(k,m:longint);
16 begin
17  if m=1 then begin write(k); exit; end;
18  print(f[k,m],m-1);
19  write(' ',k);
20 end;
21 
22 procedure topsort;
23 var t,w,i,e,v,u:longint;
24 begin
25  fillchar(b,sizeof(b),0);
26  t:=0; w:=0;
27  for i:=1 to n do
28   if d[i]=0 then begin inc(w); q[w]:=i; b[i]:=1; end;
29  while t<w do
30  begin
31   inc(t); u:=q[t];
32   e:=head[u];
33   while e<>0 do
34   begin
35    v:=vet[e];
36    for i:=1 to n-1 do
37     if dp[u,i]+len[e]<dp[v,i+1] then
38     begin
39      dp[v,i+1]:=dp[u,i]+len[e];
40      f[v,i+1]:=u;
41     end;
42    dec(d[v]);
43    e:=next[e];
44   end;
45   for i:=1 to n do
46    if (d[i]=0)and(b[i]=0) then begin inc(w); q[w]:=i; b[i]:=1; end;
47  end;
48 end;
49 
50 begin
51  //assign(input,'721C.in'); reset(input);
52  //assign(output,'721C.out'); rewrite(output);
53  readln(n,m,time);
54  for i:=1 to m do
55  begin
56   readln(x,y,z);
57   add(x,y,z);
58   inc(d[y]);
59  end;
60  for i:=1 to n do
61   for j:=1 to n do dp[i,j]:=oo;
62  dp[1,1]:=0;
63  topsort;
64  for i:=n downto 1 do
65   if dp[n,i]<=time then begin ans:=i; break; end;
66  writeln(ans);
67  print(n,ans);
68  //close(input);
69  //close(output);
70 end.

 

posted on 2016-11-09 13:25  myx12345  阅读(454)  评论(0编辑  收藏  举报

导航