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