[CSUOJ1808] 地铁(dijkstra,堆,边最短路)

题目链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1808

题意:题面挺清楚啦,就是求一个最短路。只不过每个点之间的边有可能是不同线路的,要从一个线路换到另一个线路是需要花费时间的。

边有特殊的定义,那么就不以点为分析对象做最短路了。直接拿边,dis(i)表示从1到达第i条边的指向点为终点的最短距离,每次松弛找到的边的目的点是t的时候更新一下结果。

  1 #include <algorithm>
  2 #include <iostream>
  3 #include <iomanip>
  4 #include <cstring>
  5 #include <climits>
  6 #include <complex>
  7 #include <fstream>
  8 #include <cassert>
  9 #include <cstdio>
 10 #include <bitset>
 11 #include <vector>
 12 #include <deque>
 13 #include <queue>
 14 #include <stack>
 15 #include <ctime>
 16 #include <set>
 17 #include <map>
 18 #include <cmath>
 19  
 20 using namespace std;
 21 #define fr first
 22 #define sc second
 23 #define cl clear
 24 #define BUG puts("here!!!")
 25 #define W(a) while(a--)
 26 #define pb(a) push_back(a)
 27 #define Rint(a) scanf("%d", &a)
 28 #define Rll(a) scanf("%I64d", &a)
 29 #define Rs(a) scanf("%s", a)
 30 #define Cin(a) cin >> a
 31 #define FRead() freopen("in", "r", stdin)
 32 #define FWrite() freopen("out", "w", stdout)
 33 #define Rep(i, len) for(int i = 0; i < (len); i++)
 34 #define For(i, a, len) for(int i = (a); i < (len); i++)
 35 #define Cls(a) memset((a), 0, sizeof(a))
 36 #define Clr(a, p) memset((a), (p), sizeof(a))
 37 #define Full(a) memset((a), 0x7f7f7f, sizeof(a))
 38 #define lrt rt << 1
 39 #define rrt rt << 1 | 1
 40 #define pi 3.14159265359
 41 #define RT return
 42 #define lowbit(p) p & (-p)
 43 #define onenum(p) __builtin_popcount(p)
 44 typedef long long LL;
 45 typedef long double LD;
 46 typedef unsigned long long ULL;
 47 typedef pair<int, int> pii;
 48 typedef pair<string, int> psi;
 49 typedef pair<LL, LL> pll;
 50 typedef map<string, int> msi;
 51 typedef vector<int> vi;
 52 typedef vector<LL> vl;
 53 typedef vector<vl> vvl;
 54 typedef vector<bool> vb;
 55 
 56 const LL inf = 1e18;
 57 const int maxn = 200300;
 58 typedef struct Edge {
 59     int v, c, w;
 60     int next;
 61     Edge() { next = -1; }
 62     Edge( int vv, int cc, int ww) : v(vv), c(cc), w(ww) { next = -1; }
 63 }Edge;
 64 int head[maxn], cnt;
 65 Edge edge[maxn*2];
 66 bool vis[maxn*2];
 67 LL dis[maxn*2];
 68 int n, m;
 69 
 70 void init() {
 71     Clr(head, -1); Clr(edge, -1);
 72     cnt = 0;
 73 }
 74 
 75 void adde(int u, int v, int c, int w) {
 76     edge[cnt].v = v; edge[cnt].c = c; edge[cnt].w = w;
 77     edge[cnt].next = head[u]; head[u] = cnt++;
 78 }
 79 
 80 LL dij(int s, int t) {
 81     priority_queue<pii> pq;
 82     LL ret = inf;
 83     Cls(vis);
 84     Rep(i, cnt+1) dis[i] = inf;
 85     for(int i = head[s]; ~i; i=edge[i].next) {
 86         dis[i] = edge[i].w;
 87         pq.push(pii(-dis[i], i));
 88     }
 89     while(!pq.empty()) {
 90         pii tmp = pq.top(); pq.pop();
 91         int id = tmp.second;
 92         if(vis[id]) continue;
 93         vis[id] = 1;
 94         int u = edge[id].v;
 95         if(u == t) ret = min(ret, dis[id]);
 96         for(int i = head[u]; ~i; i=edge[i].next) {
 97             int v = edge[i].v;
 98             if(!vis[i] && dis[i] > dis[id] + edge[i].w + abs(edge[id].c - edge[i].c)) {
 99                 dis[i] = dis[id] + edge[i].w + abs(edge[id].c - edge[i].c);
100                 pq.push(pii(-dis[i], i));
101             }
102         }
103     }
104     return ret;
105 }
106 
107 signed main() {
108     // FRead();
109     int u, v, c, w;
110     while(~Rint(n)&&~Rint(m)) {
111         init();
112         Rep(i, m) {
113             scanf("%d%d%d%d",&u,&v,&c,&w);
114             adde(u, v, c, w);
115             adde(v, u, c, w);
116         }
117 
118         cout << dij(1, n) << endl;
119     }
120     RT 0;
121 }
原文地址:https://www.cnblogs.com/kirai/p/5840548.html