Dijkstra algorithm (two) - the number of shortest paths, shortest paths (template)

description:

Given n cities, M undirected edges. There are a certain number of rescue teams in each city, and the rights of all sides are known. Now given the starting point and ending point, find the sum of the number of shortest paths from the starting point to the end and the number of rescue teams on the shortest path. If there are multiple shortest paths, the one with the largest sum will be output.

Example:

Input: 4 numbers in the first line, n, m, starting point, end point. The
second line is the number of rescue teams at each vertex. The
next m line is the edge weight between vertex and vertex.

5 6 0 2
1 2 1 5 3
0 1 1
0 2 2
0 3 1
1 2 1
2 4 1
3 4 1

Input: Two numbers, which are the sum of the number of the shortest path and the number of rescue teams on the shortest path.

2 4

Code:

#include<bits/stdc++.h>
using namespace std;;
const int INF = 0x3f3f3f3f;
int n,m,e[200][200],vis[200],p[200],g[200],start,end,d[200],w[200];
//顶点数,边数,邻接矩阵,是否访问,路径数目 ,救援小组数目 ,起点,终点 ,最短路 ,最大救援 
void Dijkstra(int &start){
    
    
	d[start] = 0;
	w[start] = g[start];
	p[start] = 1;
	//初始化最短路,最大救援,和路径数目 
	int min,u = -1;
	for(int i = 0;i<n ;i++){
    
    
		min = INF;
		for(int j = 0;j<n;j++){
    
    
			if(vis[j] == 0 && d[j] < min){
    
    
				min = d[j];
				u = j;
			}
		}
		//找到最小未访问
		vis[u] = 1;
		if(u == -1)	return ;
		for(int v = 0;v<n;v++){
    
    
			if(vis[v] == 0 && e[u][v] <INF){
    
     
				if(e[u][v] + d[u] < d[v]){
    
    		//如果可以松弛 
					d[v] = e[u][v] + d[u];		//更新最短路径 
					w[v] = w[u] + g[v];		//更新救援小组数目 
					p[v] = p[u]; 			//更换路径数目 
				}
				else if(e[u][v] + d[u] == d[v]){
    
    	//如果相等 
					if(w[u] + g[v] > w[v]){
    
    		//如果救援小组数目较多 
						w[v] = g[v] + w[u];		// 更新 
					}
					p[v] += p[u];				//路径数更新,写在外面 
				}
			}
		} 
	}
} 
int main(){
    
    
	freopen("a.txt","r",stdin);
	memset(e,INF,sizeof e);
	memset(p,0,sizeof p);
	memset(vis,0,sizeof vis);
	memset(d,INF,sizeof d);
	memset(w,0,sizeof w);
	cin>>n>>m>>start>>end;
	for(int i = 0;i<n;i++){
    
    
		cin>>g[i];
	}
	//读入救援小组数目 
	int u,v,k;
	for(int i = 0;i<n;i++){
    
    
		for(int j = 0;j<n;j++){
    
    
			cin>>u>>v>>k;
			e[u][v] = k;
			e[v][u] = k;
		}
	}
	//读入邻接矩阵 
	Dijkstra(start);
	cout<<p[end]<<' '<<w[end]<<endl;
	return 0;
} 

end.

Guess you like

Origin blog.csdn.net/m0_45210226/article/details/106005304