首页 > 代码库 > CSU 1808:地铁(Dijkstra)
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\n", Dijkstra());60 }61 return 0;62 }63 /*64 3 365 1 2 1 166 2 3 2 167 1 3 1 168 3 369 1 2 1 170 2 3 2 171 1 3 1 1072 3 273 1 2 1 174 2 3 1 175 */
CSU 1808:地铁(Dijkstra)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。