注意
题目是无向图,且输入的边,在后续输入时可能替换前面的边。也就是说边只会存在一条且是无向边。
#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")