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 edgeSample 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 5Sample Output
19 No Solution 475Explanation
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; }