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!\n");

66             }

67             else

68             {

69                 printf("%.3lf\n", dist[t]);

70             }

71         }

72     }

73     return 0;

74 }

 

你可能感兴趣的:(HDU)