题目背景
狗哥做烂了最短路,突然机智的考了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。
输入输出样例
输入 #1复制
3 3 1 2 3 2 3 3 1 3 10
输出 #1复制
9
说明/提示
好好看一看再写哟w
题解
这道题目和通常的最短路的最大差别在于它计算的不是边权之和,二是边权乘积。代码如下。里面只有一个小坑就是有两个测试例的数据中边长可能为9987,所以如果直接将边的成绩去模9987会产生0,从而出现错误结果。程序中对这种情况进行了特判,如果出现模后的结果为0,则将模后的结果指定为9987。
1 #include2 #include 3 #include <string.h> 4 5 using namespace std; 6 7 struct edge 8 { 9 int zhongdian, changdu; 10 int next = 0; 11 }; 12 13 int first[2333]; 14 15 edge ed[200005]; 16 17 int n, m, en; 18 19 void add_edge( int s, int e, int d ) 20 { 21 en++; 22 ed[en].next = first[s]; 23 first[s] = en; 24 ed[en].zhongdian = e; 25 ed[en].changdu = d; 26 } 27 28 29 const int MAXN = 100010; 30 const int INF = 0x3f3f3f3f; 31 int dist[MAXN]; 32 33 bool use[MAXN]; 34 35 struct rec 36 { 37 int p, dist; 38 39 rec() 40 { 41 } 42 rec( int a, int b ) 43 44 { 45 p = a, dist = b; 46 } 47 }; 48 49 bool operator < (const rec &a, const rec &b) 50 51 { 52 return(a.dist > b.dist); 53 } 54 55 priority_queue heap; 56 57 void dijkstra_heap() 58 59 { 60 memset( dist, 0x3f3f, sizeof(dist) ); 61 62 dist[1] = 1; 63 for ( int a = 1; a <= n; a++ ) 64 { 65 heap.push( rec( a, dist[a] ) ); 66 } 67 for ( int a = 1; a <= n; a++ ) 68 { 69 while ( use[heap.top().p] ) 70 { 71 heap.pop(); 72 } 73 rec now = heap.top(); 74 heap.pop(); 75 int p = now.p; 76 use[p] = true; 77 for ( int i = first[p]; i; i = ed[i].next ) 78 { 79 if ( dist[p] * ed[i].changdu < dist[ed[i].zhongdian] ) 80 81 { 82 dist[ed[i].zhongdian] = (dist[p] * ed[i].changdu) % 9987; 83 if ( dist[ed[i].zhongdian] == 0 ) 84 { 85 dist[ed[i].zhongdian] = 9987; 86 } 87 heap.push( rec( ed[i].zhongdian, dist[ed[i].zhongdian] ) ); 88 } 89 } 90 } 91 } 92 93 94 int main() 95 { 96 cin >> n >> m; 97 for ( int a = 1; a <= m; a++ ) 98 { 99 int s, e, d; 100 cin >> s >> e >> d; 101 add_edge( s, e, d ); 102 add_edge( e, s, d ); 103 } 104 dijkstra_heap(); 105 cout << dist[n] << endl; 106 return(0); 107 }