CSU 1808 地铁【思维建图+最短路Dij+Heap】

1808: 地铁

Submit Page      Summary      Time Limit: 5 Sec       Memory Limit: 128 Mb       Submitted: 1080       Solved: 255    

Description

 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

湖南省第十二届大学生计算机程序设计竞赛

思路:


1、一道经典的题型(之前刷专题的时候竟然没有关注过这类题),从u到v有两个长度的限制.很明显我们的思路不能将点作为状态去Dp了,我们要以边去作为状态去Dp是最优的,设定dist【i】表示通过第i条边到达e【i】.to所用的最短路径长度。

那么我们此时的点数是2*m个(因为边是无向边)。

又因为这样去设定的话边的条数确定不了,所以我们用Dij+堆优化更稳妥一些。


2、那么我们直接以边作为点,然后跑最短路即可,注意数据范围。


Ac代码:

#include
#include
#include
#include
using namespace std;
#define ll long long int
struct node
{
    ll from,to,w,c,next;
}e[445000];
struct node2
{
    ll u,len;
    friend bool operator <(node2 a,node2 b)
    {
        return a.len>b.len;
    }
}now,nex;
ll cont;
ll n,m;
ll vis[4050000];
ll head[150000];
ll dis[10050000];
void add(ll from,ll to,ll c,ll w)
{
    e[cont].to=to;
    e[cont].w=w;
    e[cont].c=c;
    e[cont].next=head[from];
    head[from]=cont++;
}
void Dij_Heap()
{
    memset(vis,0,sizeof(vis));
    priority_queues;
    for(ll i=0;i<=cont+10;i++)dis[i]=0x3f3f3f3f;
    for(ll i=head[1];i!=-1;i=e[i].next)
    {
        now.u=i;
        now.len=e[i].w;
        dis[i]=e[i].w;
        s.push(now);
    }
    while(!s.empty())
    {
        now=s.top();
        s.pop();
        ll u=now.u;
        if(vis[u]==1)continue;
        vis[u]=1;
        for(ll i=head[e[u].to];i!=-1;i=e[i].next)
        {
            ll v=i;
            if(dis[v]>dis[u]+e[i].w+abs(e[i].c-e[u].c))
            {
                dis[v]=dis[u]+e[i].w+abs(e[i].c-e[u].c);
                nex.u=v;
                nex.len=dis[v];
                s.push(nex);
            }
        }
    }
    ll ans=0x3f3f3f3f;
    for(ll i=0;i






你可能感兴趣的:(最短路及其拓展,思维)