注意
题目是无向图,且输入的边,在后续输入时可能替换前面的边。也就是说边只会存在一条且是无向边。
#include <iostream>
#include <vector>
using namespace std;
class Graph {
public:
//无穷
const int inf = 1e8 + 7;
//邻接矩阵,使用pair是因为有花费 e[i][j].first是距离,e[i][j].second是花费
vector<vector<pair<int, int>>> e;
int n;
Graph(int n, vector<vector<int>>& edges) {
this->n = n;
//不可达的花费和距离都是无穷
this->e = vector(n, vector<pair<int, int>>(n, {inf, inf}));
//初始化邻接矩阵,inf表示不存在边
for (auto edge : edges) {
if(edge[2]<e[edge[0]-1][edge[1]-1].first){
e[edge[0]-1][edge[1]-1]={edge[2],edge[3]};
e[edge[1]-1][edge[0]-1]={edge[2],edge[3]};
}else if(edge[2]<e[edge[0]-1][edge[1]-1].first&&edge[3]<e[edge[0]-1][edge[1]-1].second){
e[edge[0] - 1][edge[1] - 1] = {edge[2], edge[3]};
e[edge[1] - 1][edge[0] - 1] = {edge[2], edge[3]};
}
}
}
void addEdge(vector<int> edge) {
e[edge[0] - 1][edge[1] - 1] = {edge[2], edge[3]};
}
//返回node1到node2的最短距离和最短花费(距离相同是花费最少)
pair<int, int> shortestPath(int node1, int node2) {
//自己到自己是0
//求node1到其他节点i的最短路径
vector<int> dis(n, inf); //记录路径结果
vector<bool> visited(n, false); //记录已经找到最短路径的节点
vector<int> expend(n, inf); //花费
dis[node1] = 0;//自己到自己的距离为0
expend[node1] = 0; //花费为0
//进行n轮即可
for (int j = 0; j < n; j++) {
int u = -1, min_dis = inf;
//找到已经找到最短路径的dis中的最小的路径
for (int i = 0; i < n; i++) {
if (!visited[i] && dis[i] < min_dis) {
u = i;
min_dis = dis[i];
}
}
//说明不连通,有节点不可达
if (u == -1) return {-1, -1};
//说明已经到达node2
if (u == node2) {
return {dis[u], expend[u]};
}
//第一轮一定u==node1
visited[u] = true;
//更新邻居的距离和花费
for (int i = 0; i < n; i++) {
if (!visited[i] ) {
int new_dis = dis[u] + e[u][i].first, new_expend = expend[u] + e[u][i].second;
//距离优先
if (new_dis < dis[i]) {
dis[i] = new_dis;
expend[i] = new_expend;
}
//距离相同时候,花费优先
else if (new_dis == dis[i] && new_expend < expend[i])
expend[i] = new_expend;
}
}
}
//此时dis就是node1到其他节点的最短路径数组
return {-1, -1};
}
};
//Dij
int main() {
int n, m, a, b;
while (cin >> n >> m) { // 注意 while 处理多个 case
if (n == 0 && m == 0) break;
//边集合
vector<vector<int>> edges(m, vector<int>(4, 0));
for (int i = 0; i < m; i++) {
cin >> edges[i][0] >> edges[i][1] >> edges[i][2] >> edges[i][3];
}
//建图
Graph g(n, edges);
cin >> a >> b;
auto res = g.shortestPath(a - 1, b - 1);
cout << res.first << " " << res.second << endl;
}
}
// 64 位输出请用 printf("%lld")

京公网安备 11010502036488号