zoukankan      html  css  js  c++  java
  • 多源最短路 Metropolis

    牛课周周练 12 B

    传送门

    题目大意:给一张n个点,m条边的无向图(n<=2e5,m<=2e5)。现在给一些关键点,找一下离这些关键点最近的一个关键点,并且输出距离。

    分析:考虑到多源最短路(floyd)的复杂度的复杂度高达(O(n^3)),肯定是不能跑这个算法的。从小到大考虑所有关键点到其他点的距离:对于每一个点需要记录一下是哪一个关键点到这里的,距离是多少。这样的话每一个关键点,搜索时总会在另一个关键点处,或者是被另一个关键点最近的点卡住。这样的话,正确性是显然的,并且复杂度也能接受。

    #include<bits/stdc++.h>
    
    using namespace std;
    
    typedef long long LL;
    
    const LL inf = (1ll)<<60;
    
    const int N = 200005;
    
    struct Node{
        int x, y;
        LL val;
        bool operator<(const Node& a)const{
            return val>a.val;
        }
    };
    
    priority_queue<Node> q;
    
    LL d[N], ans[N];
    
    int mark[N];
    
    int head[N], Next[N<<1], weight[N<<1], to[N<<1], tot;
    
    void add_edge(int u, int v, int w){
        Next[++tot]=head[u];head[u]=tot;to[tot]=v;weight[tot]=w;
        Next[++tot]=head[v];head[v]=tot;to[tot]=u;weight[tot]=w;
    }
    
    int st[N], top;
    int n, m;
    
    inline void chmin(LL& x, LL y){x=min(x,y);}
    
    void dij(){
        for(int i=1;i<=n;++i){
            d[i]=ans[i]=inf;
        }
    
        for(int i=1;i<=top;++i){
            q.push((Node){st[i],st[i],0ll});
        }
    
        while(!q.empty()){
            Node t=q.top();
            q.pop();
    
            int u=t.x,v=t.y;
            LL val=t.val;
    
            if(!mark[v]){
                mark[v]=u;
                d[v]=val;
    
                for(int e=head[v];e;e=Next[e]){
                    int tv=to[e];
                    q.push((Node){u,tv,val+weight[e]});
    
                }
            }else if(mark[v]!=u){
                chmin(ans[u],val+d[v]);
                chmin(ans[mark[v]],val+d[v]);
            }
        }
    }
    
    int main(){
        scanf("%d%d%d", &n, &m, &top);
        for(int i=1;i<=top;++i)scanf("%d",st+i);
    
        for(int i=1;i<=m;++i){
            int u, v, w;
            scanf("%d%d%d", &u,&v,&w);
            add_edge(u,v,w);
        }
    
        dij();
    
        for(int i=1;i<=top;++i)printf("%lld ",ans[st[i]]);
        printf("
    ");
    
    
        return 0;
    }
    
    
  • 相关阅读:
    ubuntu12.04 安装CAJViewer-ubuntu(待解决)
    ROS中遇到的一些问题和解决(更新)
    Virtualbox主机和虚拟机之间文件夹共享及双向拷贝
    Ubuntu自带截图工具screenshoot
    Ubuntu vim终端常用的快捷键
    Ubuntu终端多窗口分屏Terminator
    Apollo快速安装视频教程
    ML--XOR问题
    DL之Example1--MNIST
    Python之ML--人工神经网络识别图像
  • 原文地址:https://www.cnblogs.com/JohnRan/p/13188343.html
Copyright © 2011-2022 走看看