洛谷_P2384_最短路

题目背景

狗哥做烂了最短路,突然机智的考了Bosh一道,没想到把Bosh考住了...你能帮Bosh解决吗?

他会给你100000000000000000000000000000000000%10金币w

题目描述

给定n个点的带权有向图,求从1到n的路径中边权之积最小的简单路径。

输入输出格式

输入格式:

 

第一行读入两个整数n,m,表示共n个点m条边。 接下来m行,每行三个正整数x,y,z,表示点x到点y有一条边权为z的边。

 

输出格式:

 

输出仅包括一行,记为所求路径的边权之积,由于答案可能很大,因此狗哥仁慈地让你输出它模9987的余数即可。

废话当然是一个数了w

//谢fyszzhouzj指正w

对于20%的数据,n<=10。

对于100%的数据,n<=1000,m<=1000000。边权不超过10000。

 

题解:

如标题所示,最短路,

将判断条件d[x]+w<d[y]改为d[x]*w<d[y]即可。

 

代码

 1 const
 2   mo=9987;
 3 type
 4   arr=record
 5     x,y,w,next:longint;
 6   end;
 7 var
 8   n,m,nm:longint;
 9   a:array [0..2000001] of arr;
10   ls,list,v,d:array [0..100001] of longint;
11 procedure add(x,y,z:longint);
12 begin
13   inc(nm);
14   a[nm].x:=x; a[nm].y:=y; a[nm].w:=z;
15   a[nm].next:=ls[x]; ls[x]:=nm;
16 end;
17 
18 procedure init;
19 var
20   i,x,y,z:longint;
21 begin
22   readln(n,m);
23   for i:=1 to m do
24     begin
25       readln(x,y,z);
26       add(x,y,z);
27     end;
28 end;
29 
30 procedure spfa;
31 var
32   i,head,tail:longint;
33 begin
34   fillchar(d,sizeof(d),63);
35   head:=0; tail:=1;
36   list[1]:=1; d[1]:=1; v[1]:=1;
37   repeat
38     inc(head);
39     i:=ls[list[head]];
40     while i<>0 do
41       with a[i] do
42         begin
43           if d[x]*w<d[y] then
44             begin
45               d[y]:=(d[x]*w) mod mo;
46               if v[y]=0 then
47                 begin
48                   v[y]:=1;
49                   inc(tail);
50                   list[tail]:=y;
51                 end;
52             end;
53           i:=next;
54         end;
55     v[list[head]]:=0;
56   until head>tail;
57 end;
58 
59 begin
60   init;
61   spfa;
62   writeln(d[n]);
63 end.

 

原文地址:https://www.cnblogs.com/zyx-crying/p/9478349.html