zoukankan      html  css  js  c++  java
  • [SPFA]JZOJ 3086 回家

    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
     

    Data Constraint

     
     

    Hint

    对于10%的数据m=0


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


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


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

     

    分析

    看到换站要1单位时间就想到了网络流……的建图

    我们把可以换乘的点拆成一条边就行了

    跑SPFA轻松解决

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <queue>
    using namespace std;
    const int N=2e4+10;
    const int M=1e5+10;
    struct Edge {
        int u,v,w,nx;
    }g[10*M];
    int cnt,list[2*M],d[2*M];
    bool b[2*M];
    struct Point {
        int x,y,id;
    }a[M],s,t;
    int n,m;
    
    bool CMP1(Point a,Point b) {
        return a.x<b.x||a.x==b.x&&a.y<b.y;
    }
    
    bool CMP2(Point a,Point b) {
        return a.y<b.y||a.y==b.y&&a.x<b.x;
    }
    
    void Add(int u,int v,int w) {
        g[++cnt]=(Edge){u,v,w,list[u]};list[u]=cnt;
        g[++cnt]=(Edge){v,u,w,list[v]};list[v]=cnt;
    }
    
    void SPFA(int v0) {
        queue<int> q;
        while (!q.empty()) q.pop();
        for (int i=1;i<=2*m+4;i++) d[i]=2147483647;
        d[v0]=0;b[v0]=1;
        q.push(v0);
        while (!q.empty()) {
            int u=q.front();q.pop();
            for (int i=list[u];i;i=g[i].nx)
                if (d[g[i].v]>d[u]+g[i].w) {
                    d[g[i].v]=d[u]+g[i].w;
                    if (!b[g[i].v]) q.push(g[i].v);
                    b[g[i].v]=1;
                }
            b[u]=0;
        }
    }
    
    int main() {
        scanf("%d%d",&n,&m);
        for (int i=1;i<=m;i++) scanf("%d%d",&a[i].x,&a[i].y),a[i].id=i,Add(a[i].id,a[i].id+m+2,1);
        scanf("%d%d%d%d",&s.x,&s.y,&t.x,&t.y);s.id=m+1;t.id=m+2;Add(m+1,2*m+3,0);Add(m+2,2*m+4,0);a[m+1]=s;a[m+2]=t;
        sort(a+1,a+m+3,CMP1);
        for (int i=1;i<m+2;i++) if (a[i].x==a[i+1].x) Add(a[i].id,a[i+1].id,2*(a[i+1].y-a[i].y));
        sort(a+1,a+m+3,CMP2);
        for (int i=1;i<m+2;i++) if (a[i].y==a[i+1].y) Add(a[i].id+m+2,a[i+1].id+m+2,2*(a[i+1].x-a[i].x));
        SPFA(m+1);
        printf("%d
    ",d[m+2]==2147483647?-1:d[m+2]);
    }
    View Code
    在日渐沉没的世界里,我发现了你。
  • 相关阅读:
    Aurora 数据库支持多达五个跨区域只读副本
    Amazon RDS 的 Oracle 只读副本
    Amazon EC2 密钥对
    DynamoDB 读取请求单位和写入请求单位
    使用 EBS 优化的实例或 10 Gb 网络实例
    启动 LAMP 堆栈 Web 应用程序
    AWS 中的错误重试和指数退避 Error Retries and Exponential Backoff in AWS
    使用 Amazon S3 阻止公有访问
    路由表 Router Table
    使用MySQLAdmin工具查看QPS
  • 原文地址:https://www.cnblogs.com/mastervan/p/10316779.html
Copyright © 2011-2022 走看看