题目背景
狗哥做烂了最短路,突然机智的考了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.