csu 1808 地铁 dijkstra + heap 解题报告

来源:互联网 发布:linux 挂起进程 命令 编辑:程序博客网 时间:2024/04/29 13:32

Description

 Bobo 居住在大城市 ICPCCamp。

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 所需要花费的最小时间。

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 31 2 1 12 3 2 11 3 1 13 31 2 1 12 3 2 11 3 1 103 21 2 1 12 3 1 1

Sample Output

132

代码:

#include <cstdio>#include <queue>#include <cmath>#include <string>#include <cstring>#include <iostream>#include <algorithm>#define MAX 100005#define LL long longusing namespace std;const int INF = 0x3f3f3f3f;inline void RI(int &x){      char c;      while((c=getchar())<'0' || c>'9');      x=c-'0';      while((c=getchar())>='0' && c<='9') x=(x<<3)+(x<<1)+c-'0';}struct Edge{    int v, next, num, c;}edge[MAX*2];struct Node{    int id, val;    bool operator<(const Node &a)const{        return val > a.val;    }}x;int head[MAX], vis[MAX*2], tot;LL dis[MAX*2];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 = 0; i < tot; i++)    {        dis[i] = 1e18;        vis[i] = 0;    }    for(int i = head[s]; i != -1; 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] = 1;        int u = edge[p].v;        if(u == t) ans = min(ans,dis[p]);        for(int i = head[u]; i != -1; 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, a, b, c, d;    while(scanf("%d%d", &n, &m) != EOF)    {        tot = 0;        for(int i = 1; i <= n; i++) head[i] = -1;        for(int i = 0; i < m; i++)        {            scanf("%d%d%d%d", &a, &b, &c, &d);            add_edge(a, b, c, d);        }        printf("%lld\n", dijkstra(1,n));    }    return 0;}


0 0