PAT甲1003 Emergency 两点间最短路径的条数/迪杰斯特拉/带权最短路径/fill函数

解法参考:https://blog.csdn.net/qq_43813697/article/details/89599623

题目描述

题目

Sample Input

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

Sample Output

2 4

AC代码

#include <iostream>
#define MAXV 520
using namespace std;
/*静态变量区 */ 
const int INF = 0xffff;
/*全局变量区 */
int Adj[MAXV][MAXV];  			//邻接矩阵
bool Vis[MAXV] = {false};       //是否访问过 
int Dis[MAXV],					//距离 
	W[MAXV] = {0},				//最大权重和 
	Num[MAXV] = {0};			//最短路径条数 
int Weight[MAXV]; 				//权重(救援队数量)

int N,M,C1,C2; 					//点数,路径数,起点,终点

/*
改进的迪杰斯特拉算法
求出由源点到所有其他节点的最短路径的条数
并更新权重(救援队人数) 
@param sc 源点标号 
*/
void dijkstra(int sc){
	Dis[sc] = 0;  		//到源点sc的距离为0 
	W[sc] = Weight[sc]; //到源点sc的权重和为sc自己的权重
	Num[sc] = 1;  		//到源点的最短路径数量初始为1
	for(int j = 0;j<N;++j){
	
		int minD = INF;
		int newV = -1;
		//找到Dis中值最小的
		for(int i = 0;i<N;++i){
			if(!Vis[i] && Dis[i] < minD){
				newV = i;
				minD = Dis[i];
			}
		}
	
		if(newV == -1)
			return;
		//将newV收入S点集
		Vis[newV] = true;
		//newV作为中间节点去更新 Dis
		for(int i = 0;i<N;++i){
			if(!Vis[i] && Adj[newV][i] != INF){
				
				if(Dis[newV] + Adj[newV][i] < Dis[i]){
				//如果经过newV点到i点的路径长度比原来短
					Dis[i] = Dis[newV] + Adj[newV][i];
					W[i] =  W[newV] + Weight[i];
					//如果到newV的最短路径条数为Num[newV]
					//那么到i的最短路径条数也为Num[newV]
					Num[i] = Num[newV];//重点 
					   
					
				}else if(Dis[newV] + Adj[newV][i] == Dis[i]){
				//如果经过newV点到i点的路径长度和原来一样
					if(W[i]< W[newV] + Weight[i]){
					//如果走这条路叫的救援队可以更多
						W[i] = W[newV] + Weight[i];
					} 
					//到i的最短路径条数要加上到newV的最短路径条数
					Num[i] += Num[newV]; //重点 
				}
			}
		}	
	}	
}

int main(){
	
	cin>>N>>M>>C1>>C2;
	for(int i = 0; i<N ;++i){
		cin >> Weight[i];
	}
	
	//邻接矩阵初始默认任意两点间距离无穷大
	fill(Adj[0],Adj[0]+MAXV*N,INF);	
	//到点集的距离初始默认无穷大
	fill(Dis,Dis+N,INF);
	
	int u,v,len;
	for(int i = 0;i<M;++i){
		cin>>u>>v>>len;
		Adj[v][u] = Adj[u][v] = len;
	}
	
	dijkstra(C1);
	cout<<Num[C2]<<' '<<W[C2];
	return 0;
} 

fill的使用

将一个区间的元素都赋予val值,通常可以用来初始化数组

void fill(要开始填充的数组中地址,要结束填充的数组中地址,用来填充的值)

头文件

#include <iostream>

使用fill初始化一维数组

可以根据实际需要的大小填充

int Dis[MAXV];
fill(Dis,Dis+N,INF);

使用fill初始化二维数组

由于二维数组是数组的数组,是一行一行存储的,因此如果只需要填充一部分时,需要注意在起始地址上加 n*固定列宽 。

const int INF = 0xffff;
const int MAXV = 520;
int Adj[MAXV][MAXV];
fill(Adj[0],Adj[0] + MAXV*N,INF);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值