【PTA刷题整理】PAT 甲级 1003 Emergency

2020.02.21 话不多说 直接上题


1003 Emergency (25分)

As an emergency rescue team leader of a city, you are given a special map of your country. The map shows several scattered cities connected by some roads. Amount of rescue teams in each city and the length of each road between any pair of cities are marked on the map. When there is an emergency call to you from some other city, your job is to lead your men to the place as quickly as possible, and at the mean time, call up as many hands on the way as possible.
Input Specification:

Each input file contains one test case. For each test case, the first line contains 4 positive integers: N (≤500) - the number of cities (and the cities are numbered from 0 to N−1), M - the number of roads, C​1​​ and C​2​​ - the cities that you are currently in and that you must save, respectively. The next line contains N integers, where the i-th integer is the number of rescue teams in the i-th city. Then M lines follow, each describes a road with three integers c​1​​, c​2​​ and L, which are the pair of cities connected by a road and the length of that road, respectively. It is guaranteed that there exists at least one path from C​1​​ to C​2​​.
Output Specification:

For each test case, print in one line two numbers: the number of different shortest paths between C​1​​ and C​2​​, and the maximum amount of rescue teams you can possibly gather. All the numbers in a line must be separated by exactly one space, and there is no extra space allowed at the end of a line.
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


题意为
第一行输入城市的个数citynum(看作一个点)、城市之间的道路条数roadnum(看作边数),出发城市begin以及终点城市end
第二行输入citynum个城市所含的救援队的数量(看作点的权重)
接下来输入roadnum条道路的信息,第一项为城市C1,第二项为城市C2 ,第三项为城市之间的道路长度
保证从出发城市到终点城市至少存在一条路径
求:
所给出的出发城市到终点城市最短路径的数量以及所能聚集的最大救援队数量


解题思路:
首先,题意里面写的图的顶点的数量小于500,通常使用邻接矩阵来表示图,当图的顶点大于1000的话,考虑邻接表,具体要看问题规模,以防测试点中存在某些数据导致超限
这是一个无向图求一点到某一点的最短路径问题,一般会使用Dijkstra算法或者Floyd算法,本题我们使用Dijkstra算法(没带算法书回家可愁坏了,争取熟能生巧多做类似题型把代码彻底理解背下来)采用贪心的策略,每次遍历到始点距离最近且未访问过的顶点的邻接节点,直到扩展到终点为止。


值得注意的是,在一开始做的时候很粗心没有关注最大顶点个数是500,数组开的不够大,只开了200,在评判会在后面的几组样例中出现段错误,后来改为500+就能AC了,同时可以加一个特判,到了终点就可以结束了可以节约运行时间

#include<iostream>
#include<iomanip>
#include<algorithm>
#define N 550
#define INF 99999
using namespace std;

/*
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
*/

int main(){
	//访问数组visited , 点权重weight , 距离dis , 总权重w , 最短路径路的数量shortestpath
	bool visited[N]; 
	int weight[N] , dis[N] , w[N] , shortestpath[N];
	//邻接矩阵二维数组graph表示图
	int graph[N][N]; 
	int citynum = 0 , roadnum = 0 , begin = 0 , end = 0;
	
	cin >> citynum >> roadnum >> begin >> end;
	for(int i = 0; i < citynum ; i++){
		cin >> weight[i];
	}
	//对访问标记,距离 ,无向图进行初始化 
	for(int i = 0;i < citynum ; i++){
		visited[i] = false;
		dis[i] = INF;
	}
	fill(graph[0] , graph[0] + N * N , INF);
	//输入城市之间的道路信息
	int city1 , city2 , roadlen;
	for(int i = 0;i< roadnum;i++){
		cin >> city1 >> city2 >> roadlen;
		graph[city1][city2] = graph[city2][city1] = roadlen; 
	} 
	dis[begin] = 0;
	w[begin] = weight[begin];
	shortestpath[begin] = 1;
	for(int i = 0;i < citynum;i++){
		int index = -1;
		int min = INF;
		for(int j = 0;j < citynum ; j++){
			if(visited[j] == false && dis[j] < min){
				index = j;
				min = dis[j];
			}
		}
		//已经访问完了或者不存在连通的道路时直接返回 
		if(index == -1){
			break;
		}
		visited[index] = true;
		for(int k = 0;k < citynum;k++){
		    //如果所选中点未被访问过且存在连接关系
			if(visited[k] == false && graph[index][k] != INF){
				if(dis[index] + graph[index][k] < dis[k]){
					dis[k] = dis[index] + graph[index][k];
					shortestpath[k] = shortestpath[index];
					w[k] = w[index] + weight[k];
				}
				else if(dis[index] + graph[index][k] == dis[k]){
					shortestpath[k] = shortestpath[k] + shortestpath[index];
					if(w[index] + weight[k] > w[k]){
						w[k] = w[index] + weight[k];
					}
				}	
			}
		}
		if(index == end){
			break;
		}
	}
	cout << shortestpath[end]  << " "<< w[end] << endl;
	return 0;
} 

学会了使用fill对数组和各种容器进行初始化

发布了13 篇原创文章 · 获赞 1 · 访问量 270

猜你喜欢

转载自blog.csdn.net/weixin_43849089/article/details/104432992
今日推荐