[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 }