题意:
给你一个有向图,任意一个点和边都可以经过很多次,问你整个图中,任意起点终点的k短路的长度是多少?你需要回答q个询问,每个询问给一个k
分析:
没有起点和终点,那么我们就将所有的边放到优先级队列里面,建立一个最小堆,这样就可以从堆中取出最小边权的起点,然后去扩展这个起点的下一个边和下一个点的边,这样就可以找到前k条最小的边了
链接:https://blog.csdn.net/c___c18/article/details/100085336
链接里的代码可过,我照着链接代码写了一遍一直tl
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 #include<stack> 7 #include <bitset> 8 #include<set> 9 #include<map> 10 #include<unordered_map> 11 #include<vector> 12 #include<cmath> 13 typedef long long ll; 14 using namespace std; 15 typedef pair<ll, int> pa; 16 const int N = 5e4 + 1000; 17 vector<pa>ve[N]; 18 const int INF = 0x3f3f3f3f; 19 int ans[N], maxk = 0, n, m, q, qq[N]; 20 struct node { 21 int id, now, to; 22 ll dis; 23 //优先队列进队时,权重小的放前面 24 bool operator <(const node& a)const { 25 return dis > a.dis; 26 } 27 }; 28 priority_queue<node> pr; 29 void dfs() { 30 int cnt = 0; 31 while (!pr.empty()) { 32 //选择整张图的权重最小值 33 node x = pr.top(); 34 pr.pop(); 35 node t; 36 ans[++cnt] = x.dis; 37 if (cnt >= maxk) { 38 break; 39 } 40 //当x点还有临边时,将x的下一个最短权重边加入队列 41 if (x.id + 1 < ve[x.now].size()) { 42 t.dis = x.dis - ve[x.now][x.id].first + ve[x.now][x.id + 1].first; 43 t.id = x.id + 1; 44 t.to = ve[x.now][x.id + 1].second; 45 t.now = x.now; 46 pr.push(t); 47 } 48 //若当前最短边的汇点有指向别的点的边,则取汇点y到别的边z的最短长度边,x,z加入队列 49 if (ve[x.to].size()) { 50 t.dis = x.dis + ve[x.to][0].first; 51 t.id = 0; 52 t.now = x.to; 53 t.to = ve[x.to][0].second; 54 pr.push(t); 55 } 56 } 57 } 58 int main() { 59 int T; 60 cin >> T; 61 while (T--) { 62 //清空优先队列和容器 63 while (!pr.empty()) { 64 pr.pop(); 65 } 66 cin >> n >> m >> q; 67 for (int i = 1; i <= n; i++) { 68 ve[i].clear(); 69 } 70 //将w和v放入下标为u的容器内 71 for (int i = 1; i <= m; i++) { 72 int u, v, w; 73 cin >> u >> v >> w; 74 ve[u].push_back({ w,v }); 75 } 76 //将顶点内的权重排序,把顶点到临边权重最小值放入优先队列 77 for (int i = 1; i <= n; i++) { 78 if (ve[i].size()) { 79 sort(ve[i].begin(), ve[i].end()); 80 pr.push({ 0,i,ve[i][0].second,ve[i][0].first }); 81 } 82 } 83 //找出k的最大值 84 for (int i = 1; i <= q; i++) { 85 cin >> qq[i]; 86 maxk = max(maxk, qq[i]); 87 } 88 dfs(); 89 for (int i = 1; i <= q; i++) { 90 cout << ans[qq[i]] << endl; 91 } 92 } 93 return 0; 94 }
原文:https://www.cnblogs.com/0211ji/p/13442513.html