zoukankan      html  css  js  c++  java
  • BZOJ2622 深入虎穴(最短路径)

      如果对某个点能求出与其相邻的所有点到达出口的最短时间,那么该点的答案就可以在其中取次小值了。

      对于dijkstra魔改一下就能做到这个。初始时将所有出口的最短时间设为0并放入堆,记录最短和次短路径,每个点更新后将次短路径入堆。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    #define N 100010
    #define M 2000010
    #define inf 700000000
    int n,m,k,p[N],d[N],d2[N],t=0,ans=inf;
    bool flag[N];
    struct data{int to,nxt,len;
    }edge[M];
    struct data2
    {
        int x,d;
        bool operator <(const data2&a) const
        {
            return d>a.d;
        }
    };
    priority_queue<data2> q;
    void addedge(int x,int y,int z){t++;edge[t].to=y,edge[t].nxt=p[x],edge[t].len=z,p[x]=t;}
    void dijkstra()
    {
        memset(flag,0,sizeof(flag));
        for (int i=1;i<=n;i++)
        {
            while (!q.empty()&&flag[q.top().x]) q.pop();
            if (q.empty()) break;
            data2 v=q.top();q.pop();
            flag[v.x]=1;
            for (int j=p[v.x];j;j=edge[j].nxt)
            if (v.d+edge[j].len<d[edge[j].to])
            {
                d2[edge[j].to]=d[edge[j].to];
                d[edge[j].to]=v.d+edge[j].len;
                q.push((data2){edge[j].to,d2[edge[j].to]});
            }
            else if (v.d+edge[j].len<d2[edge[j].to])
            {
                d2[edge[j].to]=v.d+edge[j].len;
                q.push((data2){edge[j].to,d2[edge[j].to]});
            }
        }
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("bzoj2622.in","r",stdin);
        freopen("bzoj2622.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        n=read(),m=read(),k=read();
        for (int i=1;i<=m;i++)
        {
            int x=read()+1,y=read()+1,z=read();
            addedge(x,y,z),addedge(y,x,z);
        }
        memset(d,42,sizeof(d));memset(d2,42,sizeof(d2));
        for (int i=1;i<=k;i++)
        {
            int x=read()+1;
            d[x]=d2[x]=0;q.push((data2){x,0});
        }
        dijkstra();
        cout<<d2[1];
        return 0;
    }
  • 相关阅读:
    LaTeX下的表格处理
    accumulate函数用法的坑
    将博客搬至CSDN
    linux; 文件名乱码;问价名出现问号
    vim打开多窗口、多文件之间的切换
    关于ssh-server
    更改Ubuntu gcc、g++默认编译器版本
    Elasticsearch nest实现类似Contains和Like功能
    Redis大幅性能提升之Batch批量读写
    Ext.NET 4.1 系统框架的搭建(后台) 附源码
  • 原文地址:https://www.cnblogs.com/Gloid/p/9584086.html
Copyright © 2011-2022 走看看