问题
有了一张自驾旅游路线图,你会知道城市间的高速公路长度、以及该公路要收取的过路费。现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径。如果有若干条路径都是最短的,那么需要输出最便宜的一条路径。
输入格式:
输入说明:输入数据的第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
解答
#include <iostream>
#include <queue>
#include <vector>
const int INFINITY = 65535;
//边节点
struct ENode
{
int V1, V2;
int Weight;
int Cost;
ENode(int u, int v, int w, int c) : V1(u), V2(v), Weight(w), Cost(c) {}
};
//边终点
struct ANode
{
//边终点下标
int Index;
int Weight;
int Cost;
ANode *Next;
ANode() : Index(0), Weight(INFINITY), Cost(0), Next(nullptr) {}
ANode(int index, int weight, int cost, ANode *next) : Index(index), Weight(weight), Cost(cost), Next(next) {}
};
//图顶点
struct VNode
{
//首插法第一条边
ANode *FirstEdge;
VNode() : FirstEdge(nullptr) {}
};
class Graph
{
public:
int Nv;
int Ne;
VNode *G;
Graph(int n1, int n2) : Nv(n1), Ne(n2)
{
G = new VNode[n1];
int u, v, w, c;
for (int i = 0; i < n2; ++i)
{
std::cin >> u >> v >> w >> c;
insert(ENode{u, v, w, c});
}
}
void insert(const ENode &E) const
{
auto *p = new ANode(E.V2, E.Weight, E.Cost, G[E.V1].FirstEdge);
G[E.V1].FirstEdge = p;
p = new ANode(E.V1, E.Weight, E.Cost, G[E.V2].FirstEdge);
G[E.V2].FirstEdge = p;
}
void print() const
{
std::cout << "*************\n";
for (int V = 0; V < Nv; ++V)
{
for (auto U = G[V].FirstEdge; U; U = U->Next)
{
std::cout << V << '-' << '-' << U->Index << ':' << U->Weight << ' ' << U->Cost << '\n';
}
std::cout << "*************\n";
}
std::cout << '\n';
}
~Graph()
{
delete[]G;
}
};
//dist全部初始化为INFINITY,path全部初始化为-1
void minDist(const Graph &g, int *dist, int *path, int *cost, int S = 0)
{
std::queue<int> Q;
dist[S] = 0;
cost[S] = 0;
Q.push(S);
while (!Q.empty())
{
int V = Q.front();
Q.pop();
for (auto U = g.G[V].FirstEdge; U; U = U->Next)
if (dist[U->Index] >= dist[V] + U->Weight)
{
if (dist[U->Index] > dist[V] + U->Weight)
{
dist[U->Index] = dist[V] + U->Weight;
cost[U->Index] = cost[V] + U->Cost;
path[U->Index] = V;
Q.push(U->Index);
} else
{
if (cost[U->Index] > cost[V] + U->Cost)
{
dist[U->Index] = dist[V] + U->Weight;
cost[U->Index] = cost[V] + U->Cost;
path[U->Index] = V;
Q.push(U->Index);
}
}
}
}
}
int main()
{
int N, M, S, D;
std::cin >> N >> M >> S >> D;
Graph g(N, M);
int *dist = new int[N];
int *path = new int[N];
int *cost = new int[N];
for (int i = 0; i < N; ++i)
{
dist[i] = INFINITY;
cost[i] = INFINITY;
path[i] = -1;
}
minDist(g, dist, path, cost, S);
// for (int i = 0; i < N; ++i) std::cout << dist[i] << ' ';
// std::cout << '\n';
// for (int i = 0; i < N; ++i) std::cout << path[i] << ' ';
// std::cout << '\n';
// for (int i = 0; i < N; ++i) std::cout << cost[i] << ' ';
// std::cout << '\n';
std::cout << dist[D] << ' ' << cost[D] << '\n';
delete[]dist;
delete[]path;
delete[]cost;
// g.print();
return 0;
}