zoukankan      html  css  js  c++  java
  • luogu P5304 [GXOI/GZOI2019]旅行者

    传送门

    所以这个(5s)是SMG

    暴力是枚举每一个点跑最短路,然后有一个很拿衣服幼稚的想法,就是把所有给出的关键点当出发点,都丢到队列里,求最短路的时候如果当前点(x)某个相邻的点(y)是关键点,就用(dis_x+)边权(w_i)更新答案.感觉这个复杂度是正确的,然后跑一下样例也对

    交上去就可以获得70'的好成绩

    这个方法会有一种特殊情况无法处理,就是这条路径的起点和终点都是同一点,因为图中可能有环.那么我们更新答案就不能用起点是(y)的路径更新答案,于是考虑同时记录从某个出发点到一个点的最短路以及是从哪个出发点转移过来的,同时求次短路,要求最短路的起点和次短路起点不一样,那么在更新答案时,如果最短路起点不等于终点就用最短路更新,否则用次短路

    // luogu-judger-enable-o2
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<vector>
    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<map>
    #include<set>
    #define LL long long
    #define db double
    
    using namespace std;
    const int N=100000+10,M=500000+10;
    int rd()
    {
        int x=0,w=1;char ch=0;
        while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
        return x*w;
    }
    int to[M],nt[M],hd[N],tot;
    LL w[M];
    void add(int x,int y,int z){++tot,to[tot]=y,nt[tot]=hd[x],w[tot]=z,hd[x]=tot;}
    bool v[N];
    struct nn
    {
        LL d;
        int y;
        void clr(){d=1ll<<50,y=0;}
        bool operator < (const nn &bb) const {return d<bb.d;}
    }d1[N],d2[N];
    struct node
    {
        int x;
        nn d1,d2;
        bool operator < (const node &bb) const {return bb.d1.d!=d1.d?bb.d1<d1:bb.d2<d2;}
    };
    priority_queue<node> q;
    int n,m,kk;
    
    int main()
    {
        int T=rd();
        while(T--)
        {
            memset(hd,0,sizeof(hd)),tot=0;
            n=rd(),m=rd(),kk=rd();
            for(int i=1;i<=m;++i)
            {
                int x=rd(),y=rd(),z=rd();
                if(x==y) continue;
                add(x,y,z);
            }
            memset(v,0,sizeof(v));
            for(int i=1;i<=n;++i) d1[i].clr(),d2[i].clr();
            LL ans=1ll<<50;
            while(kk--)
            {
                int x=rd();
                d1[x]=(nn){0,x},v[x]=1,q.push((node){x,d1[x],d2[x]});
            }
            while(!q.empty())
            {
                int x=q.top().x;
                nn dd1=q.top().d1,dd2=q.top().d2;
                q.pop();
                if(d1[x]<dd1||d2[x]<dd2) continue;
                for(int i=hd[x];i;i=nt[i])
                {
                    int y=to[i];
                    if(v[y])
                    {
                        if(dd1.y!=y) ans=min(ans,dd1.d+w[i]);
                        else ans=min(ans,dd2.d+w[i]);
                    }
                    else
                    {
                        nn n1=d1[y],n2=d2[y];
                        if(n1.d>dd2.d+w[i])
                        {
                            if(n1.y!=n2.y) n2=n1;
                            n1=(nn){dd2.d+w[i],dd2.y};
                        }
                        else if(n2.d>dd2.d+w[i]&&n1.y!=dd2.y) n2=(nn){dd2.d+w[i],dd2.y};
                        if(n1.d>dd1.d+w[i])
                        {
                            if(n1.y!=n2.y) n2=n1;
                            n1=(nn){dd1.d+w[i],dd1.y};
                        }
                        else if(n2.d>dd1.d+w[i]&&n1.y!=dd1.y) n2=(nn){dd1.d+w[i],dd1.y};
                        if(n1<d1[y]||n2<d2[y]) q.push((node){y,d1[y]=n1,d2[y]=n2});
                    }
                }
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    成绩等级
    函数值
    最大数
    温度转换
    何时使用hadoop fs、hadoop dfs与hdfs dfs命令
    Hadoop常见异常及其解决方案
    Hadoop2.4.1入门实例:MaxTemperature
    单机/伪分布式Hadoop2.4.1安装文档
    用Apache Ivy实现项目里的依赖管理
    【Nutch2.2.1基础教程之2.1】集成Nutch/Hbase/Solr构建搜索引擎之一:安装及运行【单机环境】
  • 原文地址:https://www.cnblogs.com/smyjr/p/10763331.html
Copyright © 2011-2022 走看看