1030 Travel Plan (30 分)-PAT甲级

A traveler's map gives the distances between cities along the highways(高速公路), together with the cost of each highway. Now you are supposed to write a program to help a traveler to decide the shortest path(最短路径) between his/her starting city and the destination. If such a shortest path is not unique, you are supposed to output the one with the minimum cost, which is guaranteed to be unique.

Input Specification:

Each input file contains one test case. Each case starts with a line containing 4 positive integers N, M, S, and D, where N (≤500) is the number of cities (and hence the cities are numbered from 0 to N−1); M is the number of highways; S and D are the starting and the destination cities, respectively. Then M lines follow, each provides the information of a highway, in the format:

City1 City2 Distance Cost

where the numbers are all integers no more than 500, and are separated by a space.

Output Specification:

For each test case, print in one line the cities along the shortest path from the starting point to the destination, followed by the total distance and the total cost of the path. The numbers must be separated by a space and there must be no extra space at the end of output.

Sample Input:

4 5 0 3
0 1 1 20
1 3 2 30
0 3 4 10
0 2 2 20
2 3 1 20

Sample Output:

0 2 3 3 40

题目大意:给定一张旅游地图,包括城市之间的距离和花费,要求找出从出发地到目的地之间的最短距离的路线,如果最短距离的路线有多条,就选择花费最少的最短距离的路线。 

思路:典型的最短路径问题,可以很快想到Dijkstra算法,套用Dijkstra算法的模板即可

 刷题总结:1.本题要比较的数据有cost和dist,用结构体数组存,可对结构体进行“<”运算符重载后,直接使用“<。

2.利用递归实现栈,可将Path路径按照从出发地到目的地方向进行输出,节省了栈实现所需要的大量代码。

 AC代码

#include <iostream>
#include <vector> 
#define INF 10000000
using namespace std;
vector<int> city[500];
vector<vector<int>> cost(500,vector<int>(500,INF)),dist(500,vector<int>(500,INF));
int Path[500];
bool S[500];
int n,m,c1,c2;
struct information
{
	int cost;
	int dist;
	bool operator <(information &x)
	{
		if(dist!=x.dist)
			return dist<x.dist;
		else return cost<x.cost;
	}
}D[500];
void Dijkstra()
{
	for(int i=0;i<n;i++)
	{
		S[i]=false;
		D[i]={cost[c1][i],dist[c1][i]};
		if(D[i].dist<INF)
			Path[i]=c1;
		else
			Path[i]=-1;
	}
	S[c1]=true;
	int v;
	for(int i=1;i<n;i++)
	{
		information min={INF,INF};
		for(int w=0;w<n;w++)
		{
			if(!S[w]&&D[w]<min)
			{
				min=D[w];
				v=w;
			}
		}
		S[v]=true;
		if(v==c2)
			return;
		for(int w=0;w<n;w++)
		{
			if(!S[w]&&(D[v].dist+dist[v][w]<D[w].dist||D[v].dist+dist[v][w]==D[w].dist&&D[v].cost+cost[v][w]<D[w].cost))
			{
				Path[w]=v;
				D[w]={D[v].cost+cost[v][w],D[v].dist+dist[v][w]};
			}
		}
	}
}
void print(int temp)
{
	if(temp==c1)
		cout<<temp<<" ";
	else
	{
		print(Path[temp]);
		cout<<temp<<" ";
	}
}
int main()
{
	cin>>n>>m>>c1>>c2;
	for(int i=0;i<m;i++)
	{
		int city1,city2,distance,costs;
		cin>>city1>>city2>>distance>>costs;
		city[city1].push_back(city2);
		city[city2].push_back(city1);
		cost[city1][city2]=cost[city2][city1]=costs; 
		dist[city1][city2]=dist[city2][city1]=distance; 
	}
	Dijkstra();
	print(c2);
	cout<<D[c2].dist<<" "<<D[c2].cost; 
	return 0;
}

更多PAT甲级题目:请访问PAT甲级刷题之路--题目索引+知识点分析(正在进行),感谢支持!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值