[C++] PAT 1003 Emergency (25分)

这是一个使用Dijkstra算法解决的最短路径问题,旨在找到从给定起点到各节点的最短路径以及能到达的救援队伍的最大组数。输入包含起点、终点、障碍及道路信息,输出是最短路径和能到达的救援队最大组数。
摘要由CSDN通过智能技术生成

在这里插入图片描述

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

题解

Dijkstra最短路径,另外使用一个path_num[]数组存储每个结点的最短路径条数,d_rescue[]数组存储到每个结点可到的救援队最大组数

#include <iostream>
#include <queue>
#include <map>
#include <vector>

using namespace std;

const int MAXV = 510;
const int INF = 100000;

struct cmp{

	bool operator()(pair<int,int> &a,pair<int,int> &b){
		return a.second > b.second;
	}

};

int n,m,s,t,G[MAXV][MAXV];//n结点数,m边数,s起点,t终点
int parent[MAXV];
int d[MAXV];
int rescue[MAXV];
int d_rescue[MAXV];
int path_num[MAXV];
int max_rescue_num = 0;
priority_queue<pair<int,int>,vector<pair<int,int>>,cmp> q;

void Dijsktra(){
	fill(d,d+MAXV,INF);
	fill(parent,parent+MAXV,-1);
	q.push(make_pair(s,0));

	d[s] = 0;
	d_rescue[s] = rescue[s];
	path_num[s] = 1;

	while(!q.empty()){
		pair<int,int> temp= q.top();
		q.pop();
		int first = temp.first;

		for(int i = 0;i < n;i++){
			if(G[first][i] != -1){
				int dis = d[first] + G[first][i];

				if(dis <= d[i]){


					path_num[i] = path_num[first];
					
					

					d[i] = dis;

					int re = d_rescue[first] + rescue[i];

					if(re > d_rescue[i]){
						d_rescue[i] = re;
					}

					q.push(make_pair(i,dis));
				}
				else if(dis == d[i]){
					int re = d_rescue[first] + rescue[i];

					if(re > d_rescue[i]){
						d_rescue[i] = re;
					}

					path_num[i] += path_num[first];

				}
			}
		}

	}

}


int main(){

	cin >>	n >> m >> s >> t;

	for(int i = 0; i < n; i++){
		scanf_s("%d",&rescue[i]);
	}

	fill(G[0],G[0]+MAXV*MAXV,-1);

	int temp_s,temp_t,temp_l;
	for(int i=0;i < m;i++){
		
		cin >> temp_s >> temp_t >> temp_l;
		
		G[temp_s][temp_t] = temp_l;
		G[temp_t][temp_s] = temp_l;

	}

	Dijsktra();

	
	cout << path_num[t] << " " << d_rescue[t];

	system("pause");

	return 0;

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值