【codechef】Special Shortest Walk(STL妙用,优先队列)

来源:互联网 发布:詹姆斯16总决赛数据 编辑:程序博客网 时间:2024/06/15 08:16

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,YN   X != Y source !=  sink and there are no multi edges.source and sink will not be connected by a direct edge

Sample Input

35 64 2 81 4 62 3 103 1 101 2 33 5 34 34 31 4 42 4 52 3 64 35 51 2 1002 3 803 4 904 2 852 5 1201 5

Sample Output

19No Solution475

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 500000vector< 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;}

0 0
原创粉丝点击