zoukankan      html  css  js  c++  java
  • CSU1808 地铁 —— dijkstra变形

    题目链接:http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1808


    题解:由于中转线路需要花费一定的时间,所以一般的以顶点为研究对象的dijkstra算法就不适用了,因为在松弛过程中,当前节点的最短路径不能知道是从那条线路过来的。(保存当前结点的上一站是从那条线路过来?看似可以,但是站与站之间的线路又怎么保存。矩阵?[100000][100000],内存不足。领接表?不够高效,因为要扫描链表寻找)

    所以就直接把边作为研究对象。将边的信息记录到edge中(包括两端点,线路,以及通行时间)。因为edge已经包含了线路,所以松弛时就可以直接计算了。d[i]记录从顶点1到顶点i的最短路径(题目中为时间)。


    代码如下:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<queue>
     7 #include<vector>
     8 #include<map>
     9 #include<string>
    10 #include<set>
    11 #define LL long long
    12 #define MAX(a,b) (a>b?a:b)
    13 #define MIN(a,b) (a<b?a:b)
    14 #define INF ((1<<31)-1)
    15 #define LNF ((1LL<<62)-1)
    16 #define maxn 200010
    17 
    18 using namespace std;
    19 
    20 int n,m,vis[maxn],head[maxn],tot;
    21 LL d[maxn];
    22 
    23 struct Node //记录边的信息
    24 {
    25     int v,c,t,next;
    26 }edge[maxn];
    27 
    28 void Addedge(int u, int v, int c, int t) //将与u相连通的串在一起,可以用vector
    29 {
    30     edge[tot].v = v;
    31     edge[tot].c = c;
    32     edge[tot].t = t;
    33     edge[tot].next = head[u];
    34     head[u] = tot++;
    35 }
    36 
    37 void init()
    38 {
    39     memset(head,-1,sizeof(head));
    40     tot = 0;
    41 }
    42 
    43 LL dij()
    44 {
    45     priority_queue< pair<LL,int> >q;  //队列记录花费的时间以及当前边的编号
    46     memset(vis,0,sizeof(vis));
    47 
    48     for(int i = 0; i<tot; i++)
    49         d[i] = LNF;
    50 
    51     for(int i = head[1]; i!=-1; i = edge[i].next)  //初始化,顶点1作为u的边入队
    52     {
    53         d[i] = edge[i].t;
    54         q.push(make_pair(-d[i],i));  //因为优先队列从大到小排,所以要加个负号,使其从小到大排列
    55     }
    56 
    57     while(!q.empty())
    58     {
    59         pair<LL,int>tmp = q.top();
    60         q.pop();
    61         int now = tmp.second;  //取边的编号
    62         vis[now] = 1;
    63 
    64         int u = edge[now].v;
    65         if(u==n) return d[now];  //如果当前边的v为顶点n,则找到最短路径
    66 
    67         for(int i = head[u]; i!=-1; i = edge[i].next)  //松弛
    68         {
    69             int v = edge[i].v;
    70             if(!vis[i] && d[i]>d[now]+edge[i].t + abs(edge[i].c - edge[now].c))  //abs(***)为转站花费的时间,如果相同,即为0
    71             {
    72                 d[i] = d[now] + edge[i].t + abs(edge[i].c - edge[now].c);
    73                 q.push(make_pair(-d[i],i));
    74             }
    75         }
    76     }
    77 }
    78 
    79 int main()
    80 {
    81     int u,v,c,t;
    82     while(scanf("%d%d",&n,&m)!=EOF)
    83     {
    84         init();
    85         for(int i = 0; i<m; i++)
    86         {
    87             scanf("%d%d%d%d",&u,&v,&c,&t);
    88             Addedge(u,v,c,t);
    89             Addedge(v,u,c,t);
    90         }
    91         printf("%lld
    ",dij());
    92     }
    93 }
    View Code
  • 相关阅读:
    The formatter threw an exception while trying to deserialize the message in WCF
    通过Web Deploy方式部署WCF
    The Managed Metadata Service or Connection is currently not available
    How to create Managed Metadata Column
    冒泡算法
    asp.net core 实战项目(一)——ef core的使用
    Vue学习笔记入门篇——安装及常用指令介绍
    Vue学习笔记入门篇——数据及DOM
    Vue学习笔记目录
    Chart.js在Laravel项目中的应用
  • 原文地址:https://www.cnblogs.com/DOLFAMINGO/p/7538742.html
Copyright © 2011-2022 走看看