1003 Emergency(考察迪杰斯特拉算法+第二标尺)

时间:2020-03-07
本文章向大家介绍1003 Emergency(考察迪杰斯特拉算法+第二标尺),主要包括1003 Emergency(考察迪杰斯特拉算法+第二标尺)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

 大致题意就是给出一个图、每个顶点的点权、顶点之间的边权、起点和终点。求出从起点到终点的最短路径的数量、以及最短路径上的最大点权之和。

这是一道模板题,要先记住大体流程,然后反复练习,较难头疼。。。

 1 #include<iostream>
 2 using namespace std;
 3 
 4 const int maxn = 510;
 5 const int inf = 0x3fffffff;//无穷大
 6 //第一标尺
 7 int n,m,st,ed,G[maxn][maxn];//顶点个数、邻接矩阵
 8 bool visited[maxn] = {false};//标记是否被访问过数组
 9 int d[maxn]; //从起点S到其它顶点的最短距离
10 
11 //第二标尺
12 int num[maxn];//从起点S到其它顶点的最短路径数量之和
13 int weight[maxn],w[maxn];//各个顶点的点权、从起点S到其它顶点的最大点权之和
14 
15 void dijkstra(int s) {//s为起点
16     //第一步,初始化标尺一、标尺二
17     fill(d,d+n,inf);
18     fill(num,num+n,0);
19     fill(w,w+n,0);
20     d[s] = 0;
21     num[s] = 1;
22     w[s] = weight[s];
23     //第二步,循环 n次
24     for(int i = 0; i < n; ++i) {
25         // 第三步,遍历所有顶点u,找未被访问过的使d[u]最小的顶点u
26         int u = -1, MIN = inf;
27         for(int j = 0; j < n; ++j) {
28             if(visited[j] == false && MIN > d[j]) {
29                 u = j;
30                 MIN = d[j];
31             }
32         }
33         if(u == -1) return ;//剩下的顶点和起点不连通
34         //第四步,标记 u为已访问
35         visited[u] = true;
36         //第五步,遍历所有顶点v,如果v未被访问过且u能到达v
37         for(int v = 0; v < n; ++v) {
38             if(visited[v] == false && G[u][v] != inf) {
39                 if(d[u] + G[u][v] < d[v]) {//经过u可以优化d[v]
40                     d[v] = d[u]+G[u][v]; //覆盖d[v]
41                     num[v] = num[u];     //覆盖num[v]
42                     w[v] = w[u] + weight[v];//覆盖w[v]
43                 } else if(d[u] + G[u][v] == d[v]) { //找到一条相同长度的路径
44                     if(w[u] + weight[v] > w[v])//覆盖w[v]
45                         w[v] = w[u] + weight[v];
46                     num[v] += num[u];
47                 }
48             }
49         }
50     }
51 }
52 int main() {
53     cin>>n>>m>>st>>ed;
54     for(int i = 0; i < n; ++i) cin>>weight[i]; //初始化各顶点的点权
55     //初始化邻接矩阵
56     fill(G[0],G[0]+maxn*maxn,inf);//别忘了 
57     int c1,c2,L;
58     for(int i = 0 ; i < m ; ++i) {
59         cin>>c1>>c2>>L;
60         G[c1][c2] = L;
61         G[c2][c1] = L;
62     }
63     dijkstra(st);//算法入口
64     printf("%d %d",num[ed],w[ed]);
65     return 0;
66 }

原文地址:https://www.cnblogs.com/keep23456/p/12436774.html