该题考查多条最短路径的计算,对比单条最短路,主要有两点不同:
1.在dijkstra算法中记录每个结点的所有相同最短距离的前结点
2.在dfs找多条最短路径时需要回溯状态
拿到所有最短路径以后,我们根据题意去获取相应的结果即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 int c, n, s, m; 4 typedef pair<int, int> pii; 5 vector<int> number(505); 6 vector<pii> graph[505]; 7 vector<bool> visited(505, false); 8 vector<bool> dfs_vis(505, false); 9 vector<int> dis(505, 0x3f3f3f3f); 10 vector<int> record[505]; //record[i]表示最短路径上到i点之前的点 11 set<pii> minHeap; 12 vector<vector<int>> paths; 13 14 void dijkstra() { 15 dis[0] = 0; 16 minHeap.insert(make_pair(0, 0)); 17 while(!minHeap.empty()) { 18 auto node = minHeap.begin(); 19 int root = node -> second; 20 visited[root] = true; 21 minHeap.erase(node); 22 for (auto i : graph[root]) { 23 int child = i.first; 24 int val = i.second; 25 if (!visited[child]) { 26 if (dis[child] > dis[root] + val) { 27 minHeap.erase(make_pair(dis[child], child)); 28 dis[child] = dis[root] + val; 29 minHeap.insert(make_pair(dis[child], child)); 30 //只有一个距离最短的前结点 31 record[child].clear(); 32 record[child].push_back(root); 33 } else if (dis[child] == dis[root] + val) { 34 //当存在多个距离相同的前结点时,一并记录到record数组中 35 record[child].push_back(root); 36 } 37 } 38 } 39 } 40 } 41 //根据record进行遍历,注意record中记录的是前结点,所以这时要从问题站向PBMC遍历 42 void dfs(int p, vector<int> path) { 43 path.push_back(p); 44 dfs_vis[p] = true; 45 if (p == 0) { //到达PBMC,保存当前路径 46 paths.push_back(path); 47 return; 48 } 49 for (auto i : record[p]) { 50 if (!dfs_vis[i]) { 51 vector<int> temp = path; //保留当前path信息 52 dfs(i, temp); 53 dfs_vis[i] = false; //回溯 54 } 55 } 56 57 } 58 int main() { 59 cin >> c >> n >> s >> m; 60 for (int i = 1; i <= n; ++ i) { 61 cin >> number[i]; 62 } 63 for (int i = 0; i < m; ++ i) { 64 int si, sj, t; 65 cin >> si >> sj >> t; 66 graph[si].push_back(make_pair(sj, t)); 67 graph[sj].push_back(make_pair(si, t)); 68 } 69 dijkstra(); 70 71 vector<int> temp; 72 dfs(s, temp); 73 74 int pc = c / 2; //完美情况 75 int min_send = INT32_MAX, min_back = INT32_MAX; 76 vector<int> res; //记录最终路径 77 78 // 计算所有最短路径的send和back数量 79 for (auto i : paths) { 80 int send = 0; //需要从PBMC发出的单车数量 81 int now = 0; //目前PBMCer手里有的单车数量 82 for (auto j = ++(i.rbegin()); j != i.rend(); ++ j) { 83 int station = *j; 84 if (number[station] >= pc) { //站里有多的单车 85 now += number[station] - pc; //多的单车给PBMCer 86 } else { //站里单车不够 87 if (now < pc - number[station]) { //加上PBMCer手里的也依旧不够 88 send += pc - number[station] - now; 89 now = 0; 90 } else { //PBMCer手里的够分 91 now -= pc - number[station]; 92 } 93 } 94 } 95 if (send < min_send) { 96 min_send = send; 97 res = i; 98 min_back = now; 99 } else if (send == min_send) { 100 if (now < min_back) { 101 res = i; 102 min_back = now; 103 } 104 } 105 } 106 107 cout << min_send << " "; 108 for (auto i = res.rbegin(); i != res.rend();) { 109 cout << *i; 110 if (++ i != res.rend()) { 111 cout << "->"; 112 } 113 } 114 cout << " " << min_back << endl; 115 }
标签:Management,int,back,dfs,dijkstra,vector,send,child,dis From: https://www.cnblogs.com/coderhrz/p/18548670