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 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 */
时间: 2024-09-30 03:31:04

CSU 1808:地铁(Dijkstra)的相关文章

CSU 1808 - 地铁 - [最短路变形]

题目链接:http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1808 Time limit: 5000 ms Memory limit: 131072 kB Bobo 居住在大城市 ICPCCamp. ICPCCamp 有 n 个地铁站,用 1,2,-,n 编号. m 段双向的地铁线路连接 n 个地铁站,其中第 i 段地铁属于 c i 号线,位于站 a i,b i 之间,往返均需要花费 t i 分钟(即从 a i 到 b i需要 t i 分钟,

【最短路】【STL】CSU 1808 地铁 (2016湖南省第十二届大学生计算机程序设计竞赛)

题目链接: http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1808 题目大意: N个点M条无向边(N,M<=105),每条边属于某一条地铁Ci(Ci<=109),每条边有一个耗时,如果乘Ci号线地铁到达一个节点换乘Cj号线地铁离开,还需要花费|Ci-Cj|时间. 求1到n的最小花费时间. 题目思路: [最短路][STL] d[u][Ci]表示从1到u,最后一条地铁是Ci号线的最小耗时.按照边做,每条边枚举上一个是从哪一条地铁坐过来的,更新答案

CSU 1808 地铁

湖南省第十二届大学生计算机程序设计竞赛$F$题. 最短路. 如果只记录到某个节点的最短路,显然是错误的.这题的状态有两个量决定,即到了哪一个节点,最后一辆乘坐的是几号线.这个可以用$map$记录一下. 要注意的是:如果用$SPFA$,因为要标记某个状态是否在队列中,还需要额外开一个$map$,这样可能导致超时:用$dijkstra$$+$优先队列优化的话就可以通过. #pragma comment(linker, "/STACK:1024000000,1024000000") #inc

1808: 地铁

1808: 地铁 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 693  Solved: 161[Submit][Status][Web Board] Description Bobo 居住在大城市 ICPCCamp. ICPCCamp 有 n 个地铁站,用 1,2,…,n 编号. m 段双向的地铁线路连接 n 个地铁站,其中第 i 段地铁属于 ci 号线,位于站 ai,bi 之间,往返均需要花费 ti 分钟(即从 ai 到 bi 需要 ti 分钟

地铁 Dijkstra(优先队列优化) 湖南省第五届省赛

传送门:地铁 思路:拆点,最短路:拆点比较复杂,所以对边进行最短路,spfa会tle,所以改用Dijkstra(优先队列优化) 模板 /************************************************************** Problem: User: youmi Language: C++ Result: Accepted Time: Memory: *****************************************************

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

题目链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1808 题意:题面挺清楚啦,就是求一个最短路.只不过每个点之间的边有可能是不同线路的,要从一个线路换到另一个线路是需要花费时间的. 边有特殊的定义,那么就不以点为分析对象做最短路了.直接拿边,dis(i)表示从1到达第i条边的指向点为终点的最短距离,每次松弛找到的边的目的点是t的时候更新一下结果. 1 #include <algorithm> 2 #include <iostre

双向广搜的DIJKSTRA算法--简易的北京地铁导航实现

本学期的课程设计,实现最短路的算法,于是采用了DIJKSTRA算法,并用双向广搜优化了. 实现了简易的北京地铁导航.于是把代码分享出来. (核心代码是find_min(),Dijkstra()部分) 转载或者用到里面的代码请注明博主姓名以及出处! (注:只输入了图片里的地铁站信息,所用到的文件最下面有下载,因为这些文件是我和同学一条一条的录入的,所以如果你用到请务必注明这些文件的出处) 代码: /**************************************************

地铁出行项目(续)

地铁出行项目(续) 团队成员:(特殊三人组) 杨金键 谢振威 金豪 有图有真相: 结对编程: 优点: 结对编程的时候可以一起工作,有什么错误立马发现,降低错误的概率,同时也是极好的交流学习的机会 所有人都可以专注于不同的方面,在坐一起写代码之外,如果要学新的知识,也可以分配下去各自攻克各自的任务然后再交流,这样的工作效率远比一个人要高 可以相互学习,相互借鉴,队伍里每个人都各有特点,各有所长,交流的时候进步很快 多人协作可以相互鼓励,相互督促,不容易被诱惑分心. 缺点: 分工交集的部分如果沟通不

团队项目——地铁信息查询路程规划模块初步设计

基本的数据结构为无向图.但是考虑到地铁站太多,如果把地铁站都作为此无向图中的顶点,生成的图太过复杂,这样生成最短路径算法效率肯定也不高.所以我们的思路是无向图中只保留换乘站,而两个换乘站之间的普通车站就退化成边. 基于这个思路,设计的数据结构为  线路号 开始换乘站 结束换乘站 中间普通车站数组 其中换乘站和普通站的数据结构相同,都是如下结构体 struct{ int 编号; int 里程; }station; 具体解释一下: int 编号:在获得地铁线路信息后,为了日后编写代码方便,我们需要将