题意:

  ICPCCamp 有 n 个地铁站,用 1,2,…,n 编号。 m 段双向的地铁线路连接 n 个地铁站,其中第 i 段地铁属于 ci 号线,位于站 ai,bi 之间,往返均需要花费 ti 分钟(即从 ai 到 bi 需要 ti 分钟,从 bi 到 ai 也需要 ti 分钟)。 
众所周知,换乘线路很麻烦。如果乘坐第 i 段地铁来到地铁站 s,又乘坐第 j 段地铁离开地铁站 s,那么需要额外花费 |ci-cj | 分钟。注意,换乘只能在地铁站内进行。 
Bobo 想知道从地铁站 1 到地铁站 n 所需要花费的最小时间。

分析:

  很明显的最短路,但是有两个做法.

  一是按每个站点有几个地铁经过然后拆为多个点。然后两次添加边,第一次是添加不同站点之间的花费,第二次是是相同站点不同地铁线路的话费。

  二是把边当做状态dist[i]表示走过i这条边打到edge[i].v的最少花费,这样的话就2∗m条边

spfa会TLE,所以要用dijkstra+heap

Input

输入包含不超过 20 组数据。
每组数据的第一行包含两个整数 n,m (2≤n≤105,1≤m≤105).
接下来 m 行的第 i 行包含四个整数 ai,bi,ci,ti (1≤ai,bi,ci≤n,1≤ti≤109).
保证存在从地铁站 1 到 n 的地铁线路(不一定直达)。
 

Output

对于每组数据,输出一个整数表示要求的值。

Sample Input

3 3

1 2 1 1

2 3 2 1

1 3 1 1

3 3

1 2 1 1

2 3 2 1

1 3 1 10

3 2

1 2 1 1

2 3 1 1

Sample Output

1

3

2

方法一:

  1. #include<iostream>
  2. #include<cstring>
  3. #include<cstdio>
  4. #include<vector>
  5. #include<map>
  6. #include<queue>
  7. #include<algorithm>
  8. using namespace std;
  9.  
  10. const int maxn =;
  11. const int INF = 0x3f3f3f3f;
  12.  
  13. int n,m;
  14. struct Edge{
  15. int to,next;
  16. int w;
  17. }edge[maxn*];
  18.  
  19. int head[maxn],tot;
  20.  
  21. void init(){
  22. memset(head,-,sizeof(head));
  23. tot=;
  24. }
  25. void addedge(int u,int v,int w){
  26.  
  27. edge[tot].to=v;
  28. edge[tot].next = head[u];
  29. edge[tot].w =w;
  30. head[u]=tot++;
  31. }
  32.  
  33. vector<int>num[maxn];//存贮第i个站点跟哪几个地铁相连
  34. map<int,int>mp[maxn];//存贮第i个站点跟几个地铁相连
  35.  
  36. int dis[maxn];
  37. int cnt;
  38. struct node{
  39. int now;
  40. int c;
  41. node(int _now = ,int _c=):now(_now),c(_c){}
  42. bool operator <(const node &r)const
  43. {
  44. return c>r.c;
  45. }
  46. };
  47. void DJ(){
  48.  
  49. priority_queue<node> que;
  50. while(!que.empty()) que.pop();
  51. for(int i=;i<cnt;++i) dis[i]=INF;
  52. for(int i=;i<num[].size();++i){
  53. int st;
  54. st = mp[][num[][i]];
  55. dis[st]=;
  56. que.push(node(st,));
  57. }
  58. node temp;
  59. while(!que.empty()){
  60.  
  61. temp = que.top();
  62. que.pop();
  63. int u = temp.now;
  64. int cost = temp.c;
  65. if(cost>dis[u])
  66. continue;
  67.  
  68. for(int i=head[u];~i;i=edge[i].next){
  69.  
  70. int v = edge[i].to;
  71. int w = edge[i].w;
  72. if(dis[v]>cost+w){
  73. dis[v]= cost + w;
  74. que.push(node(v,dis[v]));
  75. }
  76. }
  77. }
  78. }
  79.  
  80. int main(){
  81.  
  82. int u,v,w,x;
  83. while(scanf("%d%d",&n,&m)!=EOF){
  84.  
  85. init();
  86. cnt=;
  87. for(int i=;i<=n;i++){
  88. num[i].clear();
  89. mp[i].clear();
  90. }
  91. for(int i=;i<m;++i){
  92. scanf("%d%d%d%d",&u,&v,&x,&w);
  93. if(!mp[u][x]){
  94. mp[u][x]=cnt++;
  95. num[u].push_back(x);
  96. }
  97. u=mp[u][x];
  98. if(!mp[v][x]){
  99. mp[v][x]=cnt++;
  100. num[v].push_back(x);
  101. }
  102. v=mp[v][x];
  103. addedge(u,v,w);
  104. addedge(v,u,w);
  105. }
  106. for(int i=;i<=n;i++){
  107. sort(num[i].begin(),num[i].end());
  108. for(int j=;j<num[i].size()-;++j){
  109.  
  110. u=mp[i][num[i][j]];
  111. v=mp[i][num[i][j+]];
  112.  
  113. w=num[i][j+]-num[i][j]; //同一站点不同线路的拆点之间的差值
  114. addedge(u,v,w);
  115. addedge(v,u,w);
  116.  
  117. }
  118. }
  119. DJ();
  120. int ans=INF;
  121. for(int i=;i<num[n].size();i++){
  122. u=mp[n][num[n][i]];
  123. ans=min(ans,dis[u]);
  124.  
  125. }
  126. printf("%d\n",ans);
  127. }
  128. return ;
  129. }

方法二:

  1. #include <map>
  2. #include <set>
  3. #include <stack>
  4. #include <queue>
  5. #include <cmath>
  6. #include <string>
  7. #include <vector>
  8. #include <cstdio>
  9. #include <cctype>
  10. #include <cstring>
  11. #include <sstream>
  12. #include <cstdlib>
  13. #include <iostream>
  14. #include <algorithm>
  15.  
  16. using namespace std;
  17. #define MAX 100005
  18. #define MAXN 1000005
  19. #define LL long long
  20.  
  21. inline void RI(int &x) {
  22. char c;
  23. while((c=getchar())<'' || c>'');
  24. x=c-'';
  25. while((c=getchar())>='' && c<='') x=(x<<)+(x<<)+c-'';
  26. }
  27.  
  28. struct Edge{
  29. int v,next,num,c;
  30. }edge[MAX*];
  31.  
  32. struct Node{
  33. int id,val;
  34. bool operator<(const Node &a)const{
  35. return val>a.val;
  36. }
  37. }x;
  38.  
  39. int head[MAX];
  40. LL dis[MAX*];
  41. int vis[MAX*];
  42. int tot;
  43.  
  44. void add_edge(int a,int b,int c,int d){
  45. edge[tot]=(Edge){b,head[a],c,d};
  46. head[a]=tot++;
  47. edge[tot]=(Edge){a,head[b],c,d};
  48. head[b]=tot++;
  49. }
  50.  
  51. LL dijkstra(int s,int t){
  52. priority_queue<Node> q;
  53. for(int i=;i<tot;i++){
  54. dis[i]=1e18;
  55. vis[i]=;
  56. }
  57. for(int i=head[s];i!=-;i=edge[i].next){
  58. x=(Node){i,edge[i].c};
  59. dis[i]=edge[i].c;
  60. q.push(x);
  61. }
  62. LL ans=1e18;
  63. while(!q.empty()){
  64. x=q.top();
  65. q.pop();
  66. int p=x.id;
  67. if(vis[p]) continue;
  68. vis[p]=;
  69. int u=edge[p].v;
  70. if(u==t) ans=min(ans,dis[p]);
  71. for(int i=head[u];i!=-;i=edge[i].next){
  72. int v=edge[i].v;
  73. if(!vis[i]&&dis[i]>dis[p]+edge[i].c+abs(edge[i].num-edge[p].num)){
  74. dis[i]=dis[p]+edge[i].c+abs(edge[i].num-edge[p].num);
  75. q.push((Node){i,dis[i]});
  76. }
  77. }
  78. }
  79. return ans;
  80. }
  81. int main() {
  82. int n,m;
  83. while(cin>>n>>m){
  84. tot=;
  85. for(int i=;i<=n;i++) head[i]=-;
  86. for(int i=;i<m;i++){
  87. int a,b,c,d;
  88. RI(a);RI(b);RI(c);RI(d);
  89. add_edge(a,b,c,d);
  90. }
  91. cout<<dijkstra(,n)<<endl;
  92. }
  93. return ;
  94. }

dis[i]表示走过i这条边打到edge[i].v的最少花费 
这样的话就2∗m条边 
把边看作点来做最短路,但是这题的边数未知 
所以spfa会TLE,所以要用dijkstra+heap

CSU 1808 地铁的更多相关文章

  1. CSU 1808: 地铁 最短路

    题目链接: http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1808 1808: 地铁 Time Limit: 5 SecMemory Limit: ...

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

    题目链接: http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1808 题目大意: N个点M条无向边(N,M<=105),每条边属于某一条地铁Ci ...

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

    题目链接:http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1808 Time limit: 5000 ms Memory limit: 13107 ...

  4. CSU 1808 地铁(最短路变形)

    http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1808 题意: Bobo 居住在大城市 ICPCCamp. ICPCCamp 有 n 个地铁站, ...

  5. CSU 1808 地铁 (Dijkstra)

    Description Bobo 居住在大城市 ICPCCamp. ICPCCamp 有 n 个地铁站,用 1,2,-,n 编号. m 段双向的地铁线路连接 n 个地铁站,其中第 i 段地铁属于 ci ...

  6. CSU 1808:地铁(Dijkstra)

    http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1808 题意:…… 思路:和之前的天梯赛的一题一样,但是简单点. 没办法直接用点去算.把边看成点 ...

  7. CSUOJ 1808 地铁

    Description Bobo 居住在大城市 ICPCCamp. ICPCCamp 有 n 个地铁站,用 1,2,-,n 编号. m 段双向的地铁线路连接 n 个地铁站,其中第 i 段地铁属于 ci ...

  8. 湖南省第十二届大学生计算机程序设计竞赛 F 地铁 多源多汇最短路

    1808: 地铁 Description Bobo 居住在大城市 ICPCCamp. ICPCCamp 有 n 个地铁站,用 1,2,…,n 编号. m 段双向的地铁线路连接 n 个地铁站,其中第 i ...

  9. CSU 1809 Parenthesis(RMQ-ST+思考)

    1809: Parenthesis Submit Description Bobo has a balanced parenthesis sequence P=p1 p2…pn of length n ...

随机推荐

  1. Web Api Session开启会话支持

        1.WebApi中默认是没有开启Session会话支持的.需要在Global中重写Init方法来指定会话需要支持的类型           //代码如下 public override voi ...

  2. poj2378 树形DP

    C - 树形dp Crawling in process... Crawling failed Time Limit:1000MS     Memory Limit:65536KB     64bit ...

  3. hdu5338 ZZX and Permutations(贪心、线段树)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud ZZX and Permutations Time Limit: 6000/300 ...

  4. hdfs-over-ftp安装与配置

    hdfs-over-ftp是一个开源,简单易用的实现了对HDFS系统的下载和上传功能的小工具.可以作为管理工具来使用,快捷方便. 1 安装jdk(1.6以上版本)并配置环境变量分别执行java -ve ...

  5. window.onload,<body onload="function()">, document.onreadystatechange, httpRequest.onreadystatechang

    部分内容参考:http://www.aspbc.com/tech/showtech.asp?id=1256 在开发的过程中,经常使用window.onload和body onload两种,很少使用do ...

  6. ueditor 百度编辑器 自定义图片上传路径和格式化上传文件名

    今天项目中需要自定义图片上传的保存路径,并且不需要按照日期自动创建存储文件夹和文件名,我的ueditor版本是1.3.6.下面记录一下我配置成功的方法,如果有什么不对的地方欢迎指出,共同学习: 1:我 ...

  7. AFNetworking 使用 核心代码

    ///////////////////////////以前用法///////////////////////////////////////////////////////////// //使用AFH ...

  8. IOS 项目问题总结

    把自己项目中遇到的问题总结一下,供大家参考,希望大家多多提出意见!! 在Xcode 6.2中遇到Your build settings specify a provisioning profile w ...

  9. Here are some of my ideas .

    1:Learning english is very important ,its the very useful for my major studying and my future develo ...

  10. POJ 3709 K-Anonymous Sequence (单调队列优化)

    题意:给定一个不下降数列,一个K,将数列分成若干段,每段的数字个数不小于K,每段的代价是这段内每个数字减去这段中最小数字之和.求一种分法使得总代价最小? 思路:F[i]表示到i的最小代价.f[i]=m ...