题目链接: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 分钟,从 b i 到 a i 也需要 t i 分钟)。
众所周知,换乘线路很麻烦。如果乘坐第 i 段地铁来到地铁站 s,又乘坐第 j 段地铁离开地铁站 s,那么需要额外花费 |c i-c j | 分钟。注意,换乘只能在地铁站内进行。
Bobo 想知道从地铁站 1 到地铁站 n 所需要花费的最小时间。

Input

输入包含不超过 20 组数据。
每组数据的第一行包含两个整数 n,m (2≤n≤10 5,1≤m≤10 5).
接下来 m 行的第 i 行包含四个整数 a i,b i,c i,t i (1≤a i,b i,c i≤n,1≤t i≤10 9).
保证存在从地铁站 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

题解:

如果只记录到某个节点x的最短路长度d[x],并且记录对应于d[x],是坐哪号线来到节点x的,这样显然是错误的。

原因比如这样的样例:

3 3
1 2 1 2
1 2 3 3
2 3 3 5

可以看出,d[x]要扩展到d[x][c],即这题的状态有两个量决定:到了节点x,最后乘坐的是c号线;

那么,如果我们把节点x用若干条边Edge(u1→x)…Edge(uk→x)来代替,那么我们就相当于把d[x]要扩展到d[x][c]了;

所以我们可以直接把边当成点,对边做最短路。

(这题对边做最短路,如果用spfa的话会TLE,要使用堆优化dijkstra)

AC代码:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long LL;
typedef pair<LL,int> Pair; const LL INF=1e18;
const int maxn=1e5+;
const int maxm=2e5+; //无向边拆成两条有向边 int n,m; struct Edge{
int u,v,c;
int next;
LL t;
};
Edge E[maxm];
int head[maxn],ne;
void init()
{
ne=;
memset(head,-,sizeof(head));
}
void addedge(int u,int v,int c,LL t)
{
E[ne].u=u, E[ne].v=v, E[ne].c=c, E[ne].t=t;
E[ne].next=head[u];
head[u]=ne++;
} LL ans;
LL d[maxm];
bool vis[maxm];
void dijkstra(int st)
{
priority_queue< Pair, vector<Pair>, greater<Pair> > Q; memset(vis,,sizeof(vis));
for(int i=;i<ne;i++) d[i]=INF;
ans=INF; for(int i=head[st];i!=-;i=E[i].next)
{
d[i]=E[i].t;
Q.push(Pair(d[i],i));
}
while(!Q.empty())
{
int x=Q.top().second; Q.pop(); if(vis[x]) continue;
vis[x]=;
if(E[x].v==n) ans=min(ans,d[x]); for(int y=head[E[x].v];y!=-;y=E[y].next)
{
if(vis[y]) continue;
if(d[y]>d[x]+E[y].t+abs(E[y].c-E[x].c))
{
d[y]=d[x]+E[y].t+abs(E[y].c-E[x].c);
Q.push(Pair(d[y],y));
}
}
}
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
init();
for(int i=;i<=m;i++)
{
int u,v,c; LL t;
scanf("%d%d%d%lld",&u,&v,&c,&t);
addedge(u,v,c,t);
addedge(v,u,c,t);
} dijkstra();
printf("%lld\n",ans);
}
}
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long LL;
typedef pair<LL,int> Pair; const LL INF=1e18;
const int maxn=1e5+;
const int maxm=2e5+; //无向边拆成两条有向边 int n,m; struct Edge{
int u,v,c;
LL t;
};
vector<Edge> E;
vector<int> G[maxn];
void init(int l,int r)
{
E.clear();
for(int i=l;i<=r;i++) G[i].clear();
}
void addedge(int u,int v,int c,LL t)
{
E.push_back((Edge){u,v,c,t});
G[u].push_back(E.size()-);
} LL ans;
LL d[maxm];
bool vis[maxm];
void dijkstra(int st)
{
priority_queue< Pair, vector<Pair>, greater<Pair> > Q; memset(vis,,sizeof(vis));
for(int i=;i<E.size();i++) d[i]=INF;
ans=INF; for(int i=;i<G[st].size();i++)
{
int x=G[st][i];
d[x]=E[x].t;
Q.push(Pair(d[x],x));
}
while(!Q.empty())
{
int x=Q.top().second; Q.pop(); if(vis[x]) continue;
vis[x]=;
if(E[x].v==n) ans=min(ans,d[x]); for(int i=;i<G[E[x].v].size();i++)
{
int y=G[E[x].v][i];
if(vis[y]) continue;
if(d[y]>d[x]+E[y].t+abs(E[y].c-E[x].c))
{
d[y]=d[x]+E[y].t+abs(E[y].c-E[x].c);
Q.push(Pair(d[y],y));
}
}
}
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
init(,n);
for(int i=;i<=m;i++)
{
int u,v,c; LL t;
scanf("%d%d%d%lld",&u,&v,&c,&t);
addedge(u,v,c,t);
addedge(v,u,c,t);
} dijkstra();
printf("%lld\n",ans);
}
}

注:两份代码的区别是分别用链式前向星和vector邻接表存图。

CSU 1808 - 地铁 - [最短路变形]的更多相关文章

  1. CSU 1808: 地铁 最短路

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

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

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

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

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

  4. CSU 1808 地铁

    题意: ICPCCamp 有 n 个地铁站,用 1,2,-,n 编号. m 段双向的地铁线路连接 n 个地铁站,其中第 i 段地铁属于 ci 号线,位于站 ai,bi 之间,往返均需要花费 ti 分钟 ...

  5. CSU 1808 地铁 (Dijkstra)

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

  6. POJ-2253.Frogger.(求每条路径中最大值的最小值,最短路变形)

    做到了这个题,感觉网上的博客是真的水,只有kuangbin大神一句话就点醒了我,所以我写这篇博客是为了让最短路的入门者尽快脱坑...... 本题思路:本题是最短路的变形,要求出最短路中的最大跳跃距离, ...

  7. POJ 3635 - Full Tank? - [最短路变形][手写二叉堆优化Dijkstra][配对堆优化Dijkstra]

    题目链接:http://poj.org/problem?id=3635 题意题解等均参考:POJ 3635 - Full Tank? - [最短路变形][优先队列优化Dijkstra]. 一些口胡: ...

  8. POJ 3635 - Full Tank? - [最短路变形][优先队列优化Dijkstra]

    题目链接:http://poj.org/problem?id=3635 Description After going through the receipts from your car trip ...

  9. POJ-1797Heavy Transportation,最短路变形,用dijkstra稍加修改就可以了;

    Heavy Transportation Time Limit: 3000MS   Memory Limit: 30000K          Description Background  Hugo ...

随机推荐

  1. actor binary tree lab4

    forward 与 ! (tell) 的差异,举个例子: Main(当前actor): topNode ! Insert(requester, id=1, ele = 2) topNode: root ...

  2. swoole的进程模型架构

    swoole的强大之处就在与其进程模型的设计,既解决了异步问题,又解决了并行. 主线程MainReactor swoole启动后主线程会负责监听server socket,如果有新的连接accept, ...

  3. vuejs解析url地址

    函数: // url解析函数 // ?id=111&name=567 => {id:111,name:567} export function urlParse(){ let obj = ...

  4. 【代码审计】LaySNS_v2.2.0 System.php页面存在代码执行漏洞分析.

      0x00 环境准备 LaySNS官网:http://www.laysns.com/ 网站源码版本:LaySNS_v2.2.0 程序源码下载:https://pan.lanzou.com/i0l38 ...

  5. selenium之 chromedriver与chrome版本映射表(更新至v2.31)

    转自:http://blog.csdn.net/huilan_same/article/details/51896672 chromedriver版本 支持的Chrome版本 v2.31 v58-60 ...

  6. Perl socket编程

    In this article, let us discuss how to write Perl socket programming using the inbuilt socket module ...

  7. vi 中大小写转换功能

    所有的操作都是围绕着“gu"和“gU”另个命令展开的.secooler的语法:[开始位置]gu/Gu[结束位置]secooler的翻译: [开始位置] ---- 可以指定开始的位置,默认是光 ...

  8. 使用js是想防止表单重复提交的效果

    直接上代码: <html> <head> <title>Form表单</title> <script type="text/javasc ...

  9. 《转》win7 安装ujson 出现的“error: Microsoft Visual C++ 9.0 is required. Get it from http://aka.ms/vcpython27”

    本文转载自http://blog.csdn.net/Tilyp/article/details/72842800?locationNum=2&fps=1 我的python环境是 D:\work ...

  10. 使用JDBC插入数据到ORACLE,使用标识列自增列

    不同于SQL Server的是,Oracle中插入数据的时候,没有自增列或者是标识列,但是,我们又不想显式的进行主键的插入,这里,必须在Oracle数据库中指定一个标识列,或者说是一个序列.具体方法如 ...