PTA 7-7 旅游规划 双边权最短路 dij+堆优化

有了一张自驾旅游路线图,你会知道城市间的高速公路长度、以及该公路要收取的过路费。现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径。如果有若干条路径都是最短的,那么需要输出最便宜的一条路径。
输入格式:

输入说明:输入数据的第1行给出4个正整数N、M、S、D,其中N(2≤N≤500)是城市的个数,顺便假设城市的编号为0~(N−1);M是高速公路的条数;S是出发地的城市编号;D是目的地的城市编号。随后的M行中,每行给出一条高速公路的信息,分别是:城市1、城市2、高速公路长度、收费额,中间用空格分开,数字均为整数且不超过500。输入保证解的存在。
输出格式:

在一行里输出路径的长度和收费总额,数字间以空格分隔,输出结尾不能有多余空格。
输入样例:

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

输出样例:

3 40

样例图
在这里插入图片描述

  • 迪杰斯特拉板子题
#define debug
#ifdef debug
#include <time.h>
#include "/home/majiao/mb.h"
#endif

#include <iostream>
#include <algorithm>
#include <vector>
#include <string.h>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <math.h>

#define MAXN (512)
#define ll long long 
#define INF (0x7f7f7f7f)
#define fori(lef, rig) for(int i=lef; i<=rig; i++)
#define forj(lef, rig) for(int j=lef; j<=rig; j++)
#define fork(lef, rig) for(int k=lef; k<=rig; k++)
#define QAQ (0)

using namespace std;

#define show(x...)                             \
    do {                                       \
        cout << "\033[31;1m " << #x << " -> "; \
        err(x);                                \
    } while (0)

void err() { cout << "\033[39;0m" << endl; }
template<typename T, typename... A>
void err(T a, A... x) { cout << a << ' '; err(x...); }

namespace FastIO {

	char print_f[105];
	void read() { }
	void print() { putchar('\n'); }

	template <typename T, typename... T2>
		inline void read(T &x, T2 &... oth) {
			x = 0;
			char ch = getchar();
			ll f = 1;
			while (!isdigit(ch)) {
				if (ch == '-') f *= -1; 
				ch = getchar();
			}
			while (isdigit(ch)) {
				x = x * 10 + ch - 48;
				ch = getchar();
			}
			x *= f;
			read(oth...);
		}
	template <typename T, typename... T2>
		inline void print(T x, T2... oth) {
			ll p3=-1;
			if(x<0) putchar('-'), x=-x;
			do{
				print_f[++p3] = x%10 + 48;
			} while(x/=10);
			while(p3>=0) putchar(print_f[p3--]);
			putchar(' ');
			print(oth...);
		}
} // namespace FastIO
using FastIO::print;
using FastIO::read;


//双边权最短路  dij+堆优化
  
int n, m, Q, K, S, D;
struct Edge {
	int to, w1, w2;
} ;
vector<Edge> G[MAXN];

typedef pair<int, int> pii;
int d[MAXN], d2[MAXN];

#define inf(x) (memset(x, INF, sizeof(x)))

void dij() {
	priority_queue<pair<pii, int> > q;
	
	inf(d), inf(d2);                //初始化为无穷大

	q.push({{-d[S], -d[S]}, S}); 
	d[S] = d2[S] = 0;

	while(!q.empty()) {
		auto no = q.top(); q.pop();
		int u = no.second;
		for(auto ed : G[u]) {       //松弛每条边
			int v = ed.to;
			if(d[u]+ed.w1 < d[v]) { //松弛
				d[v] = d[u] + ed.w1;
				d2[v] = d2[u] + ed.w2;
				q.push({{-d[v], -(d2[u]+ed.w2)}, v});

			} else if(d[u]+ed.w1 == d[v]) { //边权w1相等 走w2最小的路

				d2[v] = min(d2[u] + ed.w2, d2[v]);
				q.push({{-d[v], -(d2[v])}, v});
			}
		}
	}
}

int main() {
#ifdef debug
	freopen("test", "r", stdin);
	// freopen("out_main", "w", stdout);
	clock_t stime = clock();
#endif
	read(n, m, S, D);
	int u, v, w1, w2;
	for(int i=0; i<m; i++) {
		read(u, v, w1, w2);
		G[u].push_back({v, w1, w2});
		G[v].push_back({u, w1, w2});
	}
	dij();
	//forarr(d, 0, n-1);
	//forarr(d2, 0, n-1);
	printf("%d %d\n", d[D], d2[D]);




#ifdef debug
	clock_t etime = clock();
	printf("rum time: %lf 秒\n",(double) (etime-stime)/CLOCKS_PER_SEC);
#endif 
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值