洛谷 P2384 最短路題解

題目背景

狗哥作爛了最短路,忽然機智的考了Bosh一道,沒想到把Bosh考住了...你能幫Bosh解決嗎?ios

他會給你100000000000000000000000000000000000%10金幣w測試

題目描述

給定n個點的帶權有向圖,求從1到n的路徑中邊權之積最小的簡單路徑。spa

輸入格式

第一行讀入兩個整數n,m,表示共n個點m條邊。 接下來m行,每行三個正整數x,y,z,表示點x到點y有一條邊權爲z的邊。code

輸出格式

輸出僅包括一行,記爲所求路徑的邊權之積,因爲答案可能很大,所以狗哥仁慈地讓你輸出它模9987的餘數便可。orm

廢話固然是一個數了wblog

//謝fyszzhouzj指正wci

對於20%的數據,n<=10。input

對於100%的數據,n<=1000,m<=1000000。邊權不超過10000。string

輸入輸出樣例

輸入 #1
3 3
1 2 3 
2 3 3 
1 3 10
輸出 #1
9

說明/提示

好好看一看再寫喲wit


 

題解

這道題目和一般的最短路的最大差異在於它計算的不是邊權之和,二是邊權乘積。代碼以下。裏面只有一個小坑就是有兩個測試例的數據中邊長可能爲9987,因此若是直接將邊的成績去模9987會產生0,從而出現錯誤結果。程序中對這種狀況進行了特判,若是出現模後的結果爲0,則將模後的結果指定爲9987。

  1 #include <iostream>
  2 #include <queue>
  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<rec> 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 }
相關文章
相關標籤/搜索