1 ≤ Sum of N over all test cases ≤ 100000
1 ≤ Sum of M over all test cases ≤ 500000
3 ≤ N ≤ 100000
2 ≤ M ≤ 500000
1 ≤ T ≤ 2000
1 ≤ Z ≤ 100000000
1 ≤ X,Y ≤ N
X != Y
source != sink and there are no multi edges.
source and sink will not be connected by a direct edge
Sample Input
3
5 6
4 2 8
1 4 6
2 3 10
3 1 10
1 2 3
3 5 3
4 3
4 3
1 4 4
2 4 5
2 3 6
4 3
5 5
1 2 100
2 3 80
3 4 90
4 2 85
2 5 120
1 5
Sample Output
19
No Solution
475
Explanation
For First Test Case: Shortest Valid Walk: 4->1->2->3
For Second Test Case: There is no valid Walk satisfying the constraints.
点击打开链接
优先队列priority_queue 用法详解
优先队列是队列的一种,不过它可以按照自定义的一种方式(数据的优先级)来对队列中的数据进行动态的排序
每次的push和pop操作,队列都会动态的调整,以达到我们预期的方式来存储。
例如:我们常用的操作就是对数据排序,优先队列默认的是数据大的优先级高
所以我们无论按照什么顺序push一堆数,最终在队列里总是top出最大的元素。
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
#define MAXN 100000
#define MAXM 500000
vector< pair<int, int> > L[MAXN],L2[MAXN];
struct node{
int pos,parity,last;
long long distance;
node(){}
node(int _pos, int _parity, int _last, long long _distance):
pos(_pos),parity(_parity),last(_last),distance(_distance){}
bool operator < (node X) const{
return distance > X.distance; //优先队列排序方式
}
};
long long dijkstra(int source, int sink){
priority_queue<node> Q;
Q.push(node(source,0,0,0));
while(!Q.empty()){
node cur = Q.top();
Q.pop();
if(cur.pos == sink) return cur.distance;
if(cur.parity == 1){ //第偶数个
while(!L2[cur.pos].empty()){
int w = L2[cur.pos].back().first;
if(w < cur.last){ //下一个权值比当前这个小
Q.push(node(L2[cur.pos].back().second,0,w,cur.distance + w)); //将L2里与这个点相连的点从小到大Push入
L2[cur.pos].pop_back();
} else break;
}
}
else{ //第奇数个
while(!L[cur.pos].empty()){
int w = L[cur.pos].back().first;
if(w > cur.last){
Q.push(node(L[cur.pos].back().second,1,w,cur.distance + w));
L[cur.pos].pop_back();
}else break;
}
}
}
return -1;
}
int main(){
int T,N,M,source,sink;
scanf("%d",&T);
while(T--){
scanf("%d %d",&N,&M);
for(int i = 0;i < N;++i){
L[i].clear();
L2[i].clear();
}
for(int i = 0,u,v,w;i < M;++i){
scanf("%d %d %d",&u,&v,&w);
--u; --v;
L[u].push_back(make_pair(w,v));
L[v].push_back(make_pair(w,u));
L2[u].push_back(make_pair(w,v));
L2[v].push_back(make_pair(w,u));
}
for(int i = 0;i < N;++i){
sort(L[i].begin(),L[i].end());
sort(L2[i].rbegin(),L2[i].rend()); //贪心思想,奇数位从大到小,偶数位从小到大,这样也不会相撞
}
scanf("%d %d",&source,&sink);
--source; --sink;
long long ret = dijkstra(source,sink);
if(ret == -1) printf("No Solution\n");
else printf("%lld\n",ret);
}
return 0;
}