1111 Online Map(Dijkstra)

本文介绍了一种算法,该算法能够找到从起点到终点的最短路径和最快路径。通过使用Dijkstra算法的变体,它能够在考虑距离和时间的情况下推荐两条路径:一条是最短的,另一条是最快的。在输入地图的街道交点和街道信息后,算法能够处理任意请求,并确保至少存在一条路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Input our current position and a destination, an online map can recommend several paths. Now your job is to recommend two paths to your user: one is the shortest, and the other is the fastest. It is guaranteed that a path exists for any request.

Input Specification:

Each input file contains one test case. For each case, the first line gives two positive integers N (2≤N≤500), and M, being the total number of streets intersections on a map, and the number of streets, respectively. Then M lines follow, each describes a street in the format:

V1 V2 one-way length time

where V1 and V2 are the indices (from 0 to N−1) of the two ends of the street; one-way is 1 if the street is one-way from V1 to V2, or 0 if not; length is the length of the street; and time is the time taken to pass the street.

Finally a pair of source and destination is given.

Output Specification:

For each case, first print the shortest path from the source to the destination with distance D in the format:

Distance = D: source -> v1 -> ... -> destination

Then in the next line print the fastest path with total time T:

Time = T: source -> w1 -> ... -> destination

In case the shortest path is not unique, output the fastest one among the shortest paths, which is guaranteed to be unique. In case the fastest path is not unique, output the one that passes through the fewest intersections, which is guaranteed to be unique.

In case the shortest and the fastest paths are identical, print them in one line in the format:

Distance = D; Time = T: source -> u1 -> ... -> destination

Sample Input 1:

10 15
0 1 0 1 1
8 0 0 1 1
4 8 1 1 1
3 4 0 3 2
3 9 1 4 1
0 6 0 1 1
7 5 1 2 1
8 5 1 2 1
2 3 0 2 2
2 1 1 1 1
1 3 0 3 1
1 4 0 1 1
9 7 1 3 1
5 1 0 5 2
6 5 1 1 2
3 5

Sample Output 1:

Distance = 6: 3 -> 4 -> 8 -> 5
Time = 3: 3 -> 1 -> 5

Sample Input 2:

7 9
0 4 1 1 1
1 6 1 1 3
2 6 1 1 1
2 5 1 2 2
3 0 0 1 1
3 1 1 1 3
3 2 1 1 2
4 5 0 2 2
6 5 1 1 2
3 5

Sample Output 2:

Distance = 3; Time = 4: 3 -> 2 -> 5

AC代码

#include <iostream>
#include <vector>
using namespace std;

const int maxn = 501, INF = 1000000;
struct node{
	int v, dis, time;
	node(int a, int b, int c):v(a), dis(b), time(c){}
};
vector<node> Adj[maxn];
vector<int> path1, path2;
int d[maxn], t[maxn], num[maxn];
int pre_d[maxn], pre_t[maxn];
bool vis[maxn];
int n, m, s, e;

void Dijkstra_d(){
	fill(vis, vis + maxn, false);
	for(int i = 0; i < n; i++)
		pre_d[i] = i;
	fill(d, d + maxn, INF);
	fill(t, t + maxn, INF);
	d[s] = 0;
	t[s] = 0;
	for(int i = 0; i < n; i++){
		int u = -1, min = INF;
		for(int j = 0; j < n; j++){
			if(d[j] < min && vis[j] == false){
				min = d[j];
				u = j;
			}
		}
		if(u == -1) return;
		vis[u] = true;
		for(int j = 0; j < Adj[u].size(); j++){
			int v = Adj[u][j].v;
			if(vis[v] == false){
				if(d[u] + Adj[u][j].dis < d[v]){
					d[v] = d[u] + Adj[u][j].dis;
					t[v] = t[u] + Adj[u][j].time;
					pre_d[v]= u;
				}
				else if(d[u] + Adj[u][j].dis == d[v]
				&& t[u] + Adj[u][j].time < t[v]){
					t[v] = t[u] + Adj[u][j].time;
					pre_d[v]= u;
				}
			}
		}
	} 
} 
void Dijkstra_t(){
	fill(vis, vis + maxn, false);
	for(int i = 0; i < n; i++)
		pre_t[i] = i;
	fill(t, t + maxn, INF);
	fill(num, num + maxn, INF);
	t[s] = 0;
	num[s] = 1;
	for(int i = 0; i < n; i++){
		int u = -1, min = INF;
		for(int j = 0; j < n; j++){
			if(t[j] < min && vis[j] == false){
				min = t[j];
				u = j;
			}
		}
		if(u == -1) return;
		vis[u] = true;
		for(int j = 0; j < Adj[u].size(); j++){
			int v = Adj[u][j].v;
			if(vis[v] == false){
				if(t[u] + Adj[u][j].time < t[v]){
					t[v] = t[u] + Adj[u][j].time;
					num[v] = num[u] + 1;
					pre_t[v]= u;
				}
				else if(t[u] + Adj[u][j].time == t[v]
				&& num[u] + 1 < num[v]){
					num[v] = num[u] + 1;
					pre_t[v]= u;
				}
			}
		}
	} 
}
 
void DFS_d(int v){
	if(v == s){
		path1.push_back(v);
		return;
	}	
	DFS_d(pre_d[v]);
	path1.push_back(v);
}
void DFS_t(int v){
	if(v == s){
		path2.push_back(v);
		return;
	}	
	DFS_t(pre_t[v]);
	path2.push_back(v);
}

int main(){
	cin>>n>>m;
	int u, v, one_way, dis, time;
	for(int i = 0; i < m; i++){
		cin>>u>>v>>one_way>>dis>>time;
		Adj[u].push_back(node(v, dis, time));
		if(one_way == 0)
			Adj[v].push_back(node(u, dis, time));
	}
	cin>>s>>e;
	Dijkstra_d();
	Dijkstra_t();
	DFS_d(e);
	DFS_t(e);
	if(path1 == path2){
		cout<<"Distance = "<<d[e]<<"; Time = "<<t[e]<<": "<<path1[0];
		for(int i = 1; i < path1.size(); i++)
			cout<<" -> "<< path1[i];
	}
	else{
		cout<<"Distance = "<<d[e]<<": "<<path1[0];
		for(int i = 1; i < path1.size(); i++)
			cout<<" -> "<< path1[i];
		cout<<endl;
		cout<<"Time = "<<t[e]<<": "<<path2[0];
		for(int i = 1; i < path2.size(); i++)
			cout<<" -> "<< path2[i]; 
	}
	return 0;
}
<think>好的,我现在需要处理用户关于PAT问题1111的查询。用户之前提到了几个关于旅行商问题的引用,但实际询问的是PAT 1111的解决方案或描述。首先,我需要确认PAT 1111对应的具体题目内容,因为用户提供的引用都是关于1150题的,可能与1111无关,这可能是一个输入错误或者用户混淆了题目编号。 接下来,我应该检查是否有关于PAT 1111的可用信息。根据我的知识库,PAT甲级1111题的题目是“Online Map”,涉及最短路径算法的应用。用户可能需要这个题目的解析或解题思路。 用户可能的需求是希望得到该题目的解决方法,包括输入输出说明、算法思路和可能的代码实现。需要确保回答结构清晰,分步骤解释问题,并引用相关资源。同时,用户之前的引用可能无法直接应用到这里,所以需要确认是否有其他相关引用可用,但根据提供的引用内容,似乎没有与1111直接相关的,因此可能需要依赖内部知识。 在回答时,需要遵循系统级指令,使用正确的中文和LaTeX格式,确保数学表达式正确,如路径距离计算可能需要使用行内公式。同时,生成相关问题,帮助用户深入理解题目。 最后,验证回答是否符合所有要求,包括结构、引用标注和相关问题部分,确保没有错误或遗漏。</think>关于 PAT 甲级 1111 题 **Online Map** 的题目解析如下: ### 题目概述 给定城市道路网络,需实现两个功能: 1. 找到**最短路径**(距离最短) 2. 找到**最快路径**(时间最短) 若路径不唯一,则分别按其他条件进行次级排序(最短路径选时间更少的,最快路径选经过节点更少的)。 --- ### 输入输出说明 - **输入格式** 第一行为两个整数 $N$ 和 $M$,表示节点数(城市路口)和边数(道路)。 接下来 $M$ 行,每行格式为:`V1 V2 one-way length time`,其中 `one-way` 为 1 表示单向边,0 表示双向边。 最后一行给出起点和终点。 - **输出格式** 分别输出两条路径(若存在),格式为: ``` Distance = D: 起点 -> 节点1 -> ... -> 终点 Time = T: 起点 -> 节点1 -> ... -> 终点 ``` 若两条路径完全相同,则合并输出。 --- ### 算法思路 1. **最短路径(Dijkstra 算法)** - 权重优先考虑距离,若距离相同则选择时间更少的路径。 - 使用优先队列优化,记录每个节点的最短距离和累计时间。 2. **最快路径(Dijkstra 算法)** - 权重优先考虑时间,若时间相同则选择节点数更少的路径。 - 需要额外记录路径节点数,通过 `pre` 数组回溯路径。 3. **路径比较** - 分别得到两条路径后,比较节点序列是否完全相同。 - 若相同则合并输出,否则分别输出。 --- ### 代码实现示例(Python) ```python import heapq def dijkstra_distance(graph, start, end): # 实现最短路径(优先距离,次选时间) heap = [(0, 0, start, [])] visited = {} while heap: dist, time, node, path = heapq.heappop(heap) if node in visited: continue visited[node] = (dist, time, path) if node == end: return dist, path + [node] for neighbor, (d, t) in graph[node].items(): if neighbor not in visited: heapq.heappush(heap, (dist + d, time + t, neighbor, path + [node])) return float('inf'), [] def dijkstra_time(graph, start, end): # 实现最快路径(优先时间,次选节点数) heap = [(0, 0, start, [])] visited = {} while heap: t, cnt, node, path = heapq.heappop(heap) if node in visited: continue visited[node] = (t, cnt, path) if node == end: return t, path + [node] for neighbor, (d, t_edge) in graph[node].items(): if neighbor not in visited: heapq.heappush(heap, (t + t_edge, cnt + 1, neighbor, path + [node])) return float('inf'), [] ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值