1111 Online Map (30 分)

44 篇文章 0 订阅
该博客介绍了一种求解图中两点间最短路径和最快到达路径的方法。通过Dijkstra算法的变体,同时考虑了路径长度和时间消耗。在最短路径不唯一的情况下,选择最快到达的;在最快到达路径不唯一时,选取经过最少节点的路径。程序使用C++编写,支持无向边和有向边,并且可以进行朴素版和堆优化的实现。
摘要由CSDN通过智能技术生成

题目大意:最短路!给定n个点,m条边,可能是无向边,可能是有向边,再给定两点之间的距离,时间,最后给出起点终点,求起点到终点的最短路路径和最快到达路径。

最短路路径:如果最短路不唯一,相同最短路取最快到达的路径。

最快到达路径:如果最快到达路径不唯一,输出经过最少点的路径。

如果路径相同输出 Distance = D; Time = T: source -> u1 -> ... -> destination

如果不相等输出

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

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

跑两次最短路,但是没必要写两个dijkstra,写一个dijkstra通过传参来判断求的是哪个

朴素版,和堆优化均可。

#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
typedef pair<int,int> PII;
const int N = 260010;
int e[N],ne[N],w[N],ti[N],h[N],dist[N],fast[N],path[N],idx;
bool st[N];
int n,m,s1,s2;
void add(int a,int b,int c,int d)
{
	e[idx] = b,ne[idx] = h[a],w[idx] = c,ti[idx] = d,h[a] = idx ++;
}
string pa,pb;
void dfs(int u,string &p)//取路径
{
	if(path[u] == -1)
	{   
		p += to_string(u);return ;
	}
	dfs(path[u],p);
	p = p + " -> " + to_string(u) ;
}
void dijkstra(int w1[],int w2[],int flag)
{
	memset(dist,0x3f,sizeof dist);
	memset(fast,0x3f,sizeof fast);
	memset(st,false,sizeof st);
	dist[s1] = 0,fast[s1] = 0;
	priority_queue<PII,vector<PII>,greater<PII>> que;
	que.push({0,s1});
	path[s1] = -1;
	while(que.size())
	{
		auto t = que.top();que.pop();
		int u = t.second;
		if(st[u]) continue;
		if(u == s2) break;
		st[u] = true;
		for(int i = h[u]; ~i; i = ne[i])
		{
			int j = e[i];
			if(flag) w2[i] = 1;//求最短时间需要用到集合点数
			if(!st[j] && dist[j] > dist[u] + w1[i])
			{
				dist[j] = dist[u] + w1[i];//0.最短路1.最短时间
				fast[j] = fast[u] + w2[i];//0.最短时间1.路径最少点
				path[j] = u;
				que.push({dist[j],j});
			}
			else if (dist[j] == dist[u] + w1[i] && fast[j] > fast[u] + w2[i])
			{
				fast[j]  = fast[u] + w2[i];
				path[j] = u;
			}
		}
	}
}
int main()
{
	cin.tie(0);cout.tie(0);
	cin >> n >> m;
	memset(h,-1,sizeof h);
	while(m --)
	{
		int a,b,c,d,e;
		cin >> a >> b >> c >> d >> e;
		add(a,b,d,e);
		if(!c) add(b,a,d,e);
	}
	cin >> s1 >> s2;
	dijkstra(w,ti,0);int mindist = dist[s2];dfs(s2,pa);
	dijkstra(ti,w,1);int mintime = dist[s2];dfs(s2,pb);
	if(pa == pb) printf("Distance = %d; Time = %d: %s",mindist,mintime,pa.c_str());
	else printf("Distance = %d: %s\nTime = %d: %s",mindist,pa.c_str(),mintime,pb.c_str());
	return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值