[CSU 1808: 地铁] Dijkstra
来源:互联网 发布:文明5for mac汉化 编辑:程序博客网 时间:2024/05/17 07:30
[CSU 1808: 地铁] Dijkstra
题目链接:[CSU 1808: 地铁]
题意描述:ICPCCamp 有
众所周知,换乘线路很麻烦。如果乘坐第
Bobo 想知道从地铁站
解题思路:
很明显,这是一个最短路问题。但是不能单独的以顶点为状态进行松弛操作了。因为还要考虑
- 第一种做法是以顶点编号
u 和该顶点上一条边的c 值为状态进行松弛操作,这个时候需要用map 进行对有序二元组<u,c> 进行映射一下。 - 第二种做法是以边的编号
e 为状态进行松弛操作。因为边的数目也不是很多, 也就是2∗m ,所以也不会超时。
显然,第二种做法更加简单快捷。
/** * 做法一:以顶点编号u和该顶点上一条边的c值为状态进行松弛操作 */#include <map>#include <cmath>#include <queue>#include <vector>#include <cstdio>#include <cstring>#include <iostream>using namespace std;typedef long long LL;typedef pair<int, int> PII;const int MAXN = 1e5 + 5;const int MAXE = 1e5 + 5;const LL INF = 0x3f3f3f3f3f3f3f3fLL;struct Edge { int v, w, c, next; Edge() {} Edge(int v, int c, int w, int next) : v(v), c(c), w(w), next(next) {}} edges[MAXE << 1];int N, M, head[MAXN], ESZ;map<PII, int> Hash;int tot;void init() { ESZ = 0; tot = 0; Hash.clear(); memset(head, -1, sizeof(head));}void add_edge(int u, int v, int c, int w) { edges[ESZ] = Edge(v, c, w, head[u]); head[u] = ESZ++;}struct Dij { struct QNode { int u, c; LL w; QNode() {} QNode(int u, int c, LL w) : u(u), c(c), w(w) {} bool operator > (const QNode& e)const { return w > e.w; } } cur; priority_queue<QNode, vector<QNode>, greater<QNode> > Q; LL run() { int u, v, c, w, delta, ku, kv; LL ret = INF; vector<LL> cost(tot + 1, INF); vector<bool> vis(tot + 1, false); Q.push(QNode(1, -1, 0)); ku = Hash[make_pair(1, -1)]; cost[ku] = 0; while(!Q.empty()) { cur = Q.top(); Q.pop(); u = cur.u; ku = Hash[make_pair(u, cur.c)]; if(u == N) { ret = min(ret, cost[ku]); } if(vis[ku]) continue; vis[ku] = true; for(int i = head[u]; ~i; i = edges[i].next) { v = edges[i].v, c = edges[i].c, w = edges[i].w; kv = Hash[make_pair(v, c)]; if(~cur.c) delta = abs(cur.c - c); else delta = 0; if(!vis[kv] && cost[kv] > cost[ku] + w + delta) { cost[kv] = cost[ku] + w + delta; Q.push(QNode(v, c, cost[kv])); } } } return ret; }} dij;int main() {// freopen("input.txt", "r", stdin); int u, v, c, w; while(~scanf("%d %d", &N, &M)) { init(); Hash[make_pair(1, -1)] = ++tot; for(int i = 0; i < M; i++) { scanf("%d %d %d %d", &u, &v, &c, &w); add_edge(u, v, c, w); add_edge(v, u, c, w); if(!Hash[make_pair(u, c)]) Hash[make_pair(u, c)] = ++tot; if(!Hash[make_pair(v, c)]) Hash[make_pair(v, c)] = ++tot; } LL ans = dij.run(); printf("%lld\n", ans); } return 0;}
/** * 做法二:以边的编号e为状态进行松弛操作 */#include <map>#include <cmath>#include <queue>#include <vector>#include <cstdio>#include <cstring>#include <iostream>using namespace std;typedef long long LL;typedef pair<int, int> PII;const int MAXN = 1e5 + 5;const int MAXE = 1e5 + 5;const LL INF = 0x3f3f3f3f3f3f3f3fLL;struct Edge { int v, w, c, next; Edge() {} Edge(int v, int c, int w, int next) : v(v), c(c), w(w), next(next) {}} edges[MAXE << 1];int N, M, head[MAXN], ESZ;void init() { ESZ = 0; memset(head, -1, sizeof(head));}void add_edge(int u, int v, int c, int w) { edges[ESZ] = Edge(v, c, w, head[u]); head[u] = ESZ++;}struct Dij { struct QNode { int e; LL w; QNode() {} QNode(int e, LL w) : e(e), w(w) {} bool operator > (const QNode& x)const { return w > x.w; } } cur; priority_queue<QNode, vector<QNode>, greater<QNode> > Q; LL cost[MAXE << 1]; bool vis[MAXE << 1]; LL run() { int u, w, e, delta; LL ret = INF; memset(cost, 0x3f, sizeof(cost)); memset(vis, false, sizeof(vis)); for(int i = head[1]; ~i; i = edges[i].next) { cost[i] = edges[i].w; Q.push(QNode(i, cost[i])); } while(!Q.empty()) { cur = Q.top(); Q.pop(); e = cur.e; u = edges[e].v; if(vis[e]) continue; vis[e] = true; if(u == N) ret = min(ret, cost[e]); for(int i = head[u]; ~i; i = edges[i].next) { w = edges[i].w; delta = abs(edges[e].c - edges[i].c); if(!vis[i] && cost[i] > cost[e] + w + delta) { cost[i] = cost[e] + w + delta; Q.push(QNode(i, cost[i])); } } } return ret; }} dij;int main() {// freopen("input.txt", "r", stdin); int u, v, c, w; while(~scanf("%d %d", &N, &M)) { init(); for(int i = 0; i < M; i++) { scanf("%d %d %d %d", &u, &v, &c, &w); add_edge(u, v, c, w); add_edge(v, u, c, w); } LL ans = dij.run(); printf("%lld\n", ans); } return 0;}
0 0
- [CSU 1808: 地铁] Dijkstra
- CSU 1808 地铁(dijkstra+heap)
- CSU 1808 地铁 (Dijkstra)
- csu 1808 地铁 dijkstra + heap 解题报告
- CSU 1808 地铁(Dijkstra变形+构图)
- csu 1808 地铁 dijkstra变形+优先队列优化
- CSU 1808 地铁
- CSU 1808 地铁
- csu 1808 地铁 拆点最短路
- CSU 1808 地铁【最短路变形】
- CSU 1808 地铁(最短路)
- CSU 1808 地铁(拆点最短路)
- CSU 1808 地铁 最短路变形
- CSU - 1808 地铁 (最短路,维护边)
- CSU 1808 地铁【思维建图+最短路Dij+Heap】
- Dijkstra算法之地铁修建
- 【最短路】【STL】CSU 1808 地铁 (2016湖南省第十二届大学生计算机程序设计竞赛)
- [CSU 1808(湖南省赛16)] 地铁 (拆点建图+多源多汇最短路)
- UVA 514 Rails(栈)
- mfc 对话框 toolBox 中的控件 edit control和slider control 或 spin control 使用并绑定
- Android面试经验3
- CF#678 D. Iterated Linear Function (快速幂+逆元)
- 统计数字
- [CSU 1808: 地铁] Dijkstra
- 关于LeetCode中Guess Number Higher or Lower一题的理解
- 双边滤波算法的原理、流程、实现及效果
- Linux——基本命令杂录(一)
- 基于Video4Linux 的USB 摄像头图像采集实现
- 各种滤波算法的比较
- ubuntu下编译hadoop
- 硬件控制RS485电路图设计
- centos 7 如何配置虚拟IP