CSU 1808:地铁(Dijkstra)

http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1808

题意:……

思路:和之前的天梯赛的一题一样,但是简单点。

没办法直接用点去算。把边看成点去做,规定dis[i]为走完第i条边之后即达到edge[i].v这个点的时候需要的花费。

点数为2*m。如果用普通的Dijkstra和SPFA会超时,所以用优先队列优化的Dijkstra。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define N 100010
 4 typedef long long LL;
 5 const LL INF = 1000000000000000000LL;
 6 struct Edge {
 7     int u, v, nxt, w, c;
 8 } edge[N*2];
 9 struct Node {
10     LL d; int id;
11     bool operator < (const Node &rhs) const {
12         return d > rhs.d;
13     }
14 };
15 int head[N], tot, n, m;
16 bool vis[N*2];
17 LL dis[N*2];
18 
19 void Add(int u, int v, int w, int id) {
20     edge[tot] = (Edge) { u, v, head[u], w, id}; head[u] = tot++;
21     edge[tot] = (Edge) { v, u, head[v], w, id}; head[v] = tot++;
22 }
23 
24 LL Dijkstra() {
25     for(int i = 0; i < tot; i++) dis[i] = INF;
26     memset(vis, 0, sizeof(vis));
27     LL ans = INF;
28     priority_queue<Node> que;
29     while(!que.empty()) que.pop();
30 
31     for(int i = head[1]; ~i; i = edge[i].nxt)
32         que.push((Node) {edge[i].w, i}), dis[i] = edge[i].w;
33     while(!que.empty()) {
34         Node now = que.top(); que.pop();
35         int pree = now.id; LL pred = now.d;
36         if(vis[pree]) continue; vis[pree] = 1;
37         int u = edge[pree].v;
38         if(u == n && ans > pred) ans = pred;
39         for(int i = head[u]; ~i; i = edge[i].nxt) {
40             int nowe = i;
41             LL nowd = dis[pree] + edge[nowe].w + abs(edge[nowe].c - edge[pree].c);
42             if(nowd < dis[nowe] && !vis[nowe]) {
43                 dis[nowe] = nowd;
44                 que.push((Node) { nowd, nowe });
45             }
46         }
47     }
48     return ans;
49 }
50 
51 int main() {
52     while(~scanf("%d%d", &n, &m)) {
53         memset(head, -1, sizeof(head)); tot = 0;
54         for(int i = 1; i <= m; i++) {
55             int u, v, c, w;
56             scanf("%d%d%d%d", &u, &v, &c, &w);
57             Add(u, v, w, c);
58         }
59         printf("%lld
", Dijkstra());
60     }
61     return 0;
62 }
63 /*
64 3 3
65 1 2 1 1
66 2 3 2 1
67 1 3 1 1
68 3 3
69 1 2 1 1
70 2 3 2 1
71 1 3 1 10
72 3 2
73 1 2 1 1
74 2 3 1 1
75 */
原文地址:https://www.cnblogs.com/fightfordream/p/6816906.html