hdu 1596 概率dijstra

这道题中,边权属于[0,1],并且多段路的长度为各段的乘积。联系dijstra算法的特点,我们可以采取类似于dijstra的贪心策略,每次选取到源点距离最大的点,因为现在源点到其他的点的距离都不大于这个距离,以后如果再加上某一段,总的长度便会乘上一个不大于1的数字,就更不可能比现在选取的这个距离大了,所以按照和dijstra算法一样的流程可以求出“最安全的路”。

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdio>
 5 using namespace std;
 6 
 7 const double eps = 1e-4;
 8 const int N = 1001;
 9 double g[N][N];
10 double dist[N];
11 bool visit[N];
12 int n, m;
13 
14 void dij( int s )
15 {
16     memset( visit, false, sizeof(visit) );
17     for ( int i = 0; i <= n; i++ )
18     {
19         dist[i] = 0;
20     }
21     dist[s] = 1;
22     for ( int i = 1; i <= n; i++ )
23     {
24         int u = 0;
25         for ( int j = 1; j <= n; j++ )
26         {
27             if ( !visit[j] && dist[j] > dist[u] )
28             {
29                 u = j;
30             }
31         }
32         visit[u] = true;
33         for ( int j = 1; j <= n; j++ )
34         {
35             if ( !visit[j] && g[u][j] > eps )
36             {
37                 if ( dist[u] * g[u][j] > dist[j] )
38                 {
39                     dist[j] = dist[u] * g[u][j];
40                 }
41             }
42         }
43     }
44 }
45 
46 int main ()
47 {
48     while ( scanf("%d", &n) != EOF )
49     {
50         for ( int i = 1; i <= n; i++ )
51         {
52             for ( int j = 1; j <= n; j++ )
53             {
54                 scanf("%lf", &g[i][j]);
55             }
56         }
57         scanf("%d", &m);
58         while ( m-- )
59         {
60             int s, t;
61             scanf("%d%d", &s, &t);
62             dij(s);
63             if ( dist[t] < eps )
64             {
65                 printf("What a pity!
");
66             }
67             else
68             {
69                 printf("%.3lf
", dist[t]);
70             }
71         }
72     }
73     return 0;
74 }
原文地址:https://www.cnblogs.com/huoxiayu/p/4671730.html