L2-001. 紧急救援(最短路的变形)*

L2-001. 紧急救援

 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4 int const MAX = 505;
 5 int const INF = 0x3fffffff;
 6 int mp[MAX][MAX], val[MAX], path[MAX], dis[MAX], re[MAX], totval[MAX], pathnum[MAX];
 7 bool vis[MAX];
 8 int n, m, s, d;
 9 
10 void Dijkstra(int v0)
11 {
12     for(int i = 0; i < n; i++)
13         dis[i] = INF;
14     vis[v0] = true;
15     dis[v0] = 0;
16     totval[v0] = val[v0];
17     pathnum[v0] = 1;
18     for(int i = 0; i < n; i++)
19     {
20         if(mp[v0][i] != INF && i != v0)
21         {
22             dis[i] = mp[v0][i];
23             path[i] = v0;
24             totval[i] = val[v0] + val[i];
25             pathnum[i] = 1;
26         }
27     }
28     for(int i = 0; i < n - 1; i++)
29     {
30         int mi = INF, mival = 0, u = v0;
31         for(int j = 0; j < n; j++)
32         {
33             if(!vis[j] && dis[j] < mi)
34             {
35                 mi = dis[j];
36                 u = j;
37             }
38         }
39         vis[u] = true;
40         for(int j = 0; j < n; j++)
41         {
42             if(!vis[j])
43             {
44                 if(dis[u] + mp[u][j] < dis[j])
45                 {
46                     pathnum[j] = pathnum[u];
47                     dis[j] = dis[u] + mp[u][j];
48                     totval[j] = totval[u] + val[j];
49                     path[j] = u;
50                 }
51                 else if(dis[u] + mp[u][j] == dis[j])
52                 {
53                     pathnum[j] += pathnum[u];
54                     if(totval[j] < totval[u] + val[j])
55                     {
56                         totval[j] = totval[u] + val[j];
57                         path[j] = u;
58                     }
59                 }
60             }
61         }
62     }
63 }
64 
65 int main()
66 {
67     scanf("%d %d %d %d", &n, &m, &s, &d);
68     for(int i = 0; i < n; i++)
69         scanf("%d", &val[i]);
70     for(int i = 0; i < n; i++)
71         for(int j = 0; j < n; j++)
72             mp[i][j] = INF;
73     int x, y, l;
74     for(int i = 0; i < m; i++)
75     {
76         scanf("%d %d %d", &x, &y, &l);
77         mp[x][y] = min(mp[x][y], l);
78         mp[y][x] = mp[x][y];
79     }
80     Dijkstra(s);
81     int num = 0, cur = d;
82     while(cur != s)
83     {
84         re[num ++] = cur;
85         cur = path[cur];
86     }
87     re[num ++] = s;
88     printf("%d %d
", pathnum[d], totval[d]);
89     for(int i = num - 1; i > 0; i--)
90         printf("%d ", re[i]);
91     printf("%d
", re[0]);
92 }   
原文地址:https://www.cnblogs.com/Annetree/p/8678333.html