1808: 地铁
Submit Status Time Limit: 5 Sec | Memory Limit: 128 Mb | Submitted: 870 | Solved: 202Description
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
Hint
Source
湖南省第十二届大学生计算机程序设计竞赛#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
#include <set>
#include <stack>
#include <map>
#include <climits>
#include <functional>
using namespace std;
#define LL long long
const LL INF=0x3f3f3f3f3f3f3f3f;
int n,m;
int s[100009],e[200009],nt[200009];
LL c[200009],t[200009];
LL dis[200009];
struct node
{
int id;
LL sum;
friend bool operator <(node x,node y)
{
return x.sum>y.sum;
}
}pre,nt1;
void Dijkstra(int ss)
{
for(int i=1;i<=2*m;i++) dis[i]=INF;
priority_queue<node>q;
for(int i=s[ss];~i;i=nt[i])
{
pre.id=i;
pre.sum=t[i];
dis[i]=t[i];
q.push(pre);
}
LL ans=INF;
while(!q.empty())
{
pre=q.top();
q.pop();
int id=pre.id;
int ee=e[id];
if(ee==n) ans=min(ans,dis[id]);
for(int i=s[ee];~i;i=nt[i])
{
if(dis[i]>dis[id]+t[i]+abs(c[i]-c[id]))
{
dis[i]=dis[id]+t[i]+abs(c[i]-c[id]);
nt1.id=i;
nt1.sum=dis[i];
q.push(nt1);
}
}
}
printf("%lld\n",ans);
}
int main()
{
while(~scanf("%d %d",&n,&m))
{
int cnt=1;
memset(s,-1,sizeof s);
memset(nt,-1,sizeof nt);
int ss,ee;
LL tt,cc;
for(int i=1;i<=m;i++)
{
scanf("%d %d %lld %lld",&ss,&ee,&cc,&tt);
nt[cnt]=s[ss],s[ss]=cnt,e[cnt]=ee,c[cnt]=cc,t[cnt++]=tt;
nt[cnt]=s[ee],s[ee]=cnt,e[cnt]=ss,c[cnt]=cc,t[cnt++]=tt;
}
Dijkstra(1);
}
return 0;
}