1003 Emergency(考察迪杰斯特拉算法+第二标尺)
Posted keep23456
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }
以上是关于1003 Emergency(考察迪杰斯特拉算法+第二标尺)的主要内容,如果未能解决你的问题,请参考以下文章