• 洛谷 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。

    输入输出样例

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

    说明/提示

    好好看一看再写哟w


    题解

    这道题目和通常的最短路的最大差别在于它计算的不是边权之和,二是边权乘积。代码如下。里面只有一个小坑就是有两个测试例的数据中边长可能为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 }
  • 相关阅读:
    【文字检测算法整理】
    【LDA】周志华
    【PCA】周志华
    【SVM】周志华
    4.1、顺序栈的实现(java实现)
    3.1、双向循环链表(java实现)
    5、链表队列(java实现)
    4、链栈的实现(java代码)
    3、循环链表(java实现)
    CommonsMultipartFile 转为 File 类型
  • 原文地址:https://www.cnblogs.com/zealsoft/p/11530015.html
Copyright © 2020-2023  润新知