• [spfa] Jzoj P3086 回家


    Description

    moreD城的城市轨道交通建设终于全部竣工,由于前期规划周密,建成后的轨道交通网络由 2n 条地铁线路构成,组成了一个 纵 横的交通网。如下图所示,这 2n 条线路每条线路都包含 个车站,而每个车站都在一组纵横线路的交汇处。


    出于建设成本的考虑,并非每个车站都能够进行站内换乘,能够进行站内换乘的地铁站共有 个,在下图中,标上方块标记的车站为换乘车站。已知地铁运行 站需要 分钟,而站内换乘需要步行 分钟。 你的最后一个作业就是算出,在不中途出站的前提下,从学校回家最快需要多少时间(等车时间忽略不计)。

     

     

    Input

    第一行有两个整数 n, m。接下去 行每行两个整数 x, y,表示第 条横向线路与第 条纵向线路的交汇站是站内换乘站。接下去一行是四个整数 x1,  y1,  x2,  y2。表示从学校回家时,在第 x1条横向线路与第 y1 条纵向线路的交汇站上车,在第 x2 条横向线路与第 y2 条纵向线路的交汇站下车。

    Output

    仅一个整数表示在合理选择线路的情况下,回家所需要的最少时间。如果无法在不出站换车的情况下回家则输出-1.

     

    Sample Input

    Sample Input 1
    6 9
    2 1
    2 5
    3 2
    4 4
    5 2
    5 6
    6 1
    6 3
    6 4
    1 1 4 6
    
    Sample Input 2
    6 10
    2 1
    2 5
    3 2
    4 4
    5 2
    5 6
    6 1
    6 3
    6 4
    6 6
    1 1 4 6
    
    Sample Input 3
    2 1
    1 2
    1 1 2 2

    Sample Output

    Sample Output 1
    27
    
    Sample Output 2 
    26
    
    Sample Output 3
    5
     

    Hint

    对于10%的数据m=0


    对于 30%的数据,≤ 50, m ≤ 1000


    对于 60%的数据,≤ 500, m ≤ 2000


    对于 100%的数据,≤ 20000, m ≤ 100000

    题解

    • 题目大意:给定一个n*n的图,有n个可以转向的交点(横纵变化),每次转向需要1的代价,每走一个站需要2的代价,问从起点到终点的最小代价
    • 显然,我们可以对于一个点拆成两个点(横纵),然后对于每个转向的点的横纵相连,代价为1
    • 同行同列相连,代价为距离*2,起点和终点横纵转换可以不用代价,因为可以起点可以任意开始,终点也可以从上下到达
    • 建完图就可以直接跑spfa(不怕被卡的话)

    代码

     1 #include <cstdio>
     2 #include <queue>
     3 #include <algorithm>
     4 #define inf 0x7fffffff
     5 #define N 200010
     6 using namespace std;
     7 struct node { int to,from,v; }E[N*4];
     8 struct edge { int x,y,d; }e[N];
     9 int n,m,cnt,head[N*4],dis[N],vis[N];
    10 queue<int> Q;
    11 bool cmp(edge a,edge b) { return (a.x==b.x)?a.y<b.y:a.x<b.x; }
    12 bool CMP(edge a,edge b) { return (a.y==b.y)?a.x<b.x:a.y<b.y; }
    13 void insert(int x,int y,int v) 
    14 { 
    15     E[++cnt].to=y,E[cnt].from=head[x],E[cnt].v=v,head[x]=cnt; 
    16     E[++cnt].to=x,E[cnt].from=head[y],E[cnt].v=v,head[y]=cnt; 
    17 }
    18 int spfa()
    19 {
    20     for (int i=1;i<=(m+2)*2;i++) dis[i]=inf;
    21     vis[m+1]=1,dis[m+1]=0,Q.push(m+1);
    22     while (!Q.empty())
    23     {
    24         int u=Q.front(); Q.pop(),vis[u]=0;
    25         for (int i=head[u];i;i=E[i].from)
    26             if (dis[E[i].to]>dis[u]+E[i].v)
    27             {
    28                 dis[E[i].to]=dis[u]+E[i].v;
    29                 if (!vis[E[i].to]) vis[E[i].to]=1,Q.push(E[i].to);
    30             }
    31     }
    32     return dis[m+2]==inf?-1:dis[m+2];
    33 }
    34 int main()
    35 {
    36     scanf("%d%d",&n,&m);
    37     for (int i=1;i<=m+2;i++) scanf("%d%d",&e[i].x,&e[i].y),e[i].d=i;
    38     sort(e+1,e+m+2+1,cmp);
    39     for (int i=1;i<m+2;i++) if (e[i].x==e[i+1].x) insert(e[i].d,e[i+1].d,2*(e[i+1].y-e[i].y));
    40     sort(e+1,e+m+2+1,CMP);
    41     for (int i=1;i<m+2;i++) if (e[i].y==e[i+1].y) insert(e[i].d+m+2,e[i+1].d+m+2,2*(e[i+1].x-e[i].x));
    42     for (int i=1;i<=m;i++) insert(i,i+m+2,1);
    43     insert(m+1,m+m+3,0),insert(m+2,(m+2)*2,0);
    44     printf("%d",spfa());
    45 }
  • 相关阅读:
    BigDecimal 相除时因除不尽报错
    Spring Boot 构建项目时报错:You need to run build with JDK or have tools.jar on the classpath.If this occures during eclipse build make sure you run eclipse under JDK as well (com.mysema.maven:apt-maven-plugi
    JSP页面进入时不加载数据列表
    JSP页面乱码解决方案
    JSP中直接在输入框中校验
    数据存储过程及计算
    Python 基础入门 7_4 内置模块(Math模块以及随机数模块)
    Python 基础入门 8 异常处理及文件处理
    Python 基础入门 7_3 内置模块(OS模块)
    Python 基础入门 7_2 内置模块(时间模块)
  • 原文地址:https://www.cnblogs.com/Comfortable/p/10310804.html
Copyright © 2020-2023  润新知