Problem Description
You have a directed weighted graph with n
vertexes and m
edges. The value of a path is the sum of the weight of the edges you passed. Note that you can pass any edge any times and every time you pass it you will gain the weight.
Now there are q
queries that you need to answer. Each of the queries is about the k-th minimum value of all the paths.
Input
The input consists of multiple test cases, starting with an integer t
(1≤t≤100)
, denoting the number of the test cases.
The first line of each test case contains three positive integers n,m,q. (1≤n,m,q≤5∗104)
Each of the next m
lines contains three integers ui,vi,wi
, indicating that the i−th
edge is from ui
to vi
and weighted wi
.(1≤ui,vi≤n,1≤wi≤109)
Each of the next q
lines contains one integer k
as mentioned above.(1≤k≤5∗104)
It‘s guaranteed that Σn
,Σm
, Σq,Σmax(k)≤2.5∗105
and max(k)
won‘t exceed the number of paths in the graph.
Output
For each query, print one integer indicates the answer in line.
Sample Input
1
2 2 2
1 2 1
2 1 2
3
4
Sample Output
3
3
Hint
1->2 value :1
2->1 value: 2
1-> 2-> 1 value: 3
2-> 1-> 2 value: 3
题意:题意很简单,就是给你一张单向图,求Q个询问,问整个图的第Q【i】长度路径
思路:开始的时候,是直接暴力添边,直到第k大,但是寻思可能MLE,自作聪明的对队列限制只能加入MAXX个(最大的询问值),超过了就直接和队列的最大值比较。
但是这样是TLE的,因为可能会有菊花图,对于一个点如果直接扩展其所有连边就容易TLE. 复杂度 T*k*log(k*n)
所以我们考虑,对于一条已知的最小边,需要如何扩展,很明显我们可以拓展其出点的最小出边,这肯定是下一个最小的候选答案,因为该边是由入点扩展的一条边,那么如果该入点还有比该边权值大的边,也扩展它,这样就保证了最小的边一定被扩展出来了,后面重复过程,直到计算完MAXX.
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 5e4+5; 5 int n,m,k,t,q; 6 typedef pair<int,int>p; 7 typedef long long ll; 8 vector<p>node[maxn]; 9 10 ll ans[maxn]; 11 int Q[maxn]; 12 13 struct Point 14 { 15 ll val; 16 int now,id; 17 Point(ll val,int now,int id):val(val),now(now),id(id){} 18 bool operator<(const Point &b)const{ 19 return val > b.val; 20 } 21 }; 22 23 priority_queue<Point>que; 24 void bfs(int limit) 25 { 26 while(!que.empty())que.pop(); 27 for(int i=1;i<=n;i++)sort(node[i].begin(),node[i].end()); 28 for(int i=1;i<=n;i++) 29 { 30 if(!node[i].empty())que.push(Point(node[i][0].first,i,0)); 31 } 32 int tot = 0; 33 while(!que.empty()) 34 { 35 Point tmp = que.top(); 36 que.pop(); 37 ll cost = tmp.val; 38 int now = tmp.now; 39 int id = tmp.id; 40 if(++tot > limit)return; 41 ans[tot] = cost; 42 if(id < node[now].size() - 1) 43 { 44 que.push(Point(cost-node[now][id].first+node[now][id+1].first,now,id+1)); 45 } 46 if(!node[node[now][id].second].empty()) 47 { 48 que.push(Point(cost+node[node[now][id].second][0].first,node[now][id].second,0)); 49 } 50 } 51 } 52 53 int main() 54 { 55 scanf("%d",&t); 56 while(t--) 57 { 58 scanf("%d%d%d",&n,&m,&q); 59 int maxx = 0; 60 for(int i=1;i<=n;i++)node[i].clear(); 61 for(int i=1;i<=m;i++) 62 { 63 int u,v,w; 64 scanf("%d%d%d",&u,&v,&w); 65 node[u].push_back(p(w,v)); 66 } 67 for(int i=1;i<=q;i++) 68 { 69 scanf("%d",&Q[i]); 70 maxx = max(maxx,Q[i]); 71 } 72 bfs(maxx); 73 for(int i=1;i<=q;i++) 74 { 75 printf("%lld\n",ans[Q[i]]); 76 } 77 } 78 }
原文地址:https://www.cnblogs.com/iwannabe/p/11402800.html