题意:

  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

方法一:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<map>
#include<queue>
#include<algorithm>
using namespace std; const int maxn =;
const int INF = 0x3f3f3f3f; int n,m;
struct Edge{
int to,next;
int w;
}edge[maxn*]; int head[maxn],tot; void init(){
memset(head,-,sizeof(head));
tot=;
}
void addedge(int u,int v,int w){ edge[tot].to=v;
edge[tot].next = head[u];
edge[tot].w =w;
head[u]=tot++;
} vector<int>num[maxn];//存贮第i个站点跟哪几个地铁相连
map<int,int>mp[maxn];//存贮第i个站点跟几个地铁相连 int dis[maxn];
int cnt;
struct node{
int now;
int c;
node(int _now = ,int _c=):now(_now),c(_c){}
bool operator <(const node &r)const
{
return c>r.c;
}
};
void DJ(){ priority_queue<node> que;
while(!que.empty()) que.pop();
for(int i=;i<cnt;++i) dis[i]=INF;
for(int i=;i<num[].size();++i){
int st;
st = mp[][num[][i]];
dis[st]=;
que.push(node(st,));
}
node temp;
while(!que.empty()){ temp = que.top();
que.pop();
int u = temp.now;
int cost = temp.c;
if(cost>dis[u])
continue; for(int i=head[u];~i;i=edge[i].next){ int v = edge[i].to;
int w = edge[i].w;
if(dis[v]>cost+w){
dis[v]= cost + w;
que.push(node(v,dis[v]));
}
}
}
} int main(){ int u,v,w,x;
while(scanf("%d%d",&n,&m)!=EOF){ init();
cnt=;
for(int i=;i<=n;i++){
num[i].clear();
mp[i].clear();
}
for(int i=;i<m;++i){
scanf("%d%d%d%d",&u,&v,&x,&w);
if(!mp[u][x]){
mp[u][x]=cnt++;
num[u].push_back(x);
}
u=mp[u][x];
if(!mp[v][x]){
mp[v][x]=cnt++;
num[v].push_back(x);
}
v=mp[v][x];
addedge(u,v,w);
addedge(v,u,w);
}
for(int i=;i<=n;i++){
sort(num[i].begin(),num[i].end());
for(int j=;j<num[i].size()-;++j){ u=mp[i][num[i][j]];
v=mp[i][num[i][j+]]; w=num[i][j+]-num[i][j]; //同一站点不同线路的拆点之间的差值
addedge(u,v,w);
addedge(v,u,w); }
}
DJ();
int ans=INF;
for(int i=;i<num[n].size();i++){
u=mp[n][num[n][i]];
ans=min(ans,dis[u]); }
printf("%d\n",ans);
}
return ;
}

方法二:

#include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <sstream>
#include <cstdlib>
#include <iostream>
#include <algorithm> using namespace std;
#define MAX 100005
#define MAXN 1000005
#define LL long long inline void RI(int &x) {
char c;
while((c=getchar())<'' || c>'');
x=c-'';
while((c=getchar())>='' && c<='') x=(x<<)+(x<<)+c-'';
} struct Edge{
int v,next,num,c;
}edge[MAX*]; struct Node{
int id,val;
bool operator<(const Node &a)const{
return val>a.val;
}
}x; int head[MAX];
LL dis[MAX*];
int vis[MAX*];
int tot; void add_edge(int a,int b,int c,int d){
edge[tot]=(Edge){b,head[a],c,d};
head[a]=tot++;
edge[tot]=(Edge){a,head[b],c,d};
head[b]=tot++;
} LL dijkstra(int s,int t){
priority_queue<Node> q;
for(int i=;i<tot;i++){
dis[i]=1e18;
vis[i]=;
}
for(int i=head[s];i!=-;i=edge[i].next){
x=(Node){i,edge[i].c};
dis[i]=edge[i].c;
q.push(x);
}
LL ans=1e18;
while(!q.empty()){
x=q.top();
q.pop();
int p=x.id;
if(vis[p]) continue;
vis[p]=;
int u=edge[p].v;
if(u==t) ans=min(ans,dis[p]);
for(int i=head[u];i!=-;i=edge[i].next){
int v=edge[i].v;
if(!vis[i]&&dis[i]>dis[p]+edge[i].c+abs(edge[i].num-edge[p].num)){
dis[i]=dis[p]+edge[i].c+abs(edge[i].num-edge[p].num);
q.push((Node){i,dis[i]});
}
}
}
return ans;
}
int main() {
int n,m;
while(cin>>n>>m){
tot=;
for(int i=;i<=n;i++) head[i]=-;
for(int i=;i<m;i++){
int a,b,c,d;
RI(a);RI(b);RI(c);RI(d);
add_edge(a,b,c,d);
}
cout<<dijkstra(,n)<<endl;
}
return ;
}

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. Enable-Migrations 在应用程序配置文件中找不到xx连接字符串

    在解决方案中有多个项目时,使用Enable-Migrations 命令进行数据迁移时,出现以下错误: 尝试在Enable-Migrations 命令中指定-projectName也不行,最后将要操作的 ...

  2. Winform 无边框随意拖动【转载】

    本篇技术内容转载自:http://www.cnblogs.com/ap0606122/archive/2012/10/23/2734964.html using System; using Syste ...

  3. PL/SQL中字符串变量的分割转化

    在编写PL/SQL时,有时候我们需要处理这样一个输入的变量,它的格式是由多个值通过分隔符组成的字符串,如“1,2,3”,我们需要将这个变量加入到我们的SQL中,形成诸如in('1','2','3')的 ...

  4. rsync数据同步配置

    环境配置 操作系统:centos6.4_64bit A服务器IP:192.168.6.128 B服务器IP:192.168.6.129 以A服务器为基准,将A服务器文件同步到B服务器. 步骤如下: 开 ...

  5. 流输入练习——寻找Sb.VI codevs 3096

    题目描述 Description 已知某开放授权人员名叫Serb,由于经常修改各种数据,因此开发人员们都喊他SB.现在他和许多人一起过飞机安检,排成了一长队列,请问SB.是否在队列中. 输入描述 In ...

  6. [翻译] C++ STL容器参考手册 (总册)

    1. 写在最前面 这将是博主的第一篇技术博客,思考再三决定从翻译开始.这将是一个系列的博客,由不同的章节组成,章节之间由超链接联系,开发过程将使用增量式开发,每次完成一个章节.本篇是本系列的总册,提供 ...

  7. Qt窗口句柄

    关键字: 透明效果,异形,子窗口,控件,浮窗,同级句柄

  8. 【Nutch2.2.1源代码分析之5】索引的基本流程

    一.各个主要类之间的关系 SolrIndexerJob extends IndexerJob 1.IndexerJob:主要完成 2.SolrIndexerJob:主要完成 3.IndexUtil:主 ...

  9. J2EE 基础知识积累

    1. 面向对象的思维: 1. 有哪些类 那些对象      2. 这些类中,每种类应该具有某种属性和方法      3. 考虑类与类之间应该具有什么样的关系 3. 1. 成员变量可以使用java语言中 ...

  10. C# 数据实现设计模式

    一个人没事,写了一个底层数据实现读取设计模式,个人觉得还是蛮好扩展,里面有不足的地方希望大家给予指导.话不多说先看个图吧!图可能不正规,伤害了你的眼睛见谅.有图有真相 其实这个设计模式,就是一个简单的 ...