1 条题解

  • 0
    @ 2025-8-24 22:01:27

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar SuperJvRuo
    **

    搬运于2025-08-24 22:01:27,当前版本为作者最后更新于2018-05-12 17:09:57,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    套路题,分层图。

    以样例为例(使用 @EternalAlexander 这位dalao的OI Painter绘制):

    各层内部正常连边,各层之间从上到下连权值为0的边。每向下跑一层,就相当于免费搭一次飞机。跑一遍从sst+nkt+n*k的最短路即可。

    #include<cstdio>
    #include<cctype>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    #include<vector>
    #include<utility> 
    #include<functional>
    
    int Read()
    {
        int x=0;char c=getchar();
        while(!isdigit(c))
        {
            c=getchar();
        }
        while(isdigit(c))
        {
            x=x*10+(c^48);
            c=getchar();
        }
        return x;
    }
    
    using std::priority_queue;
    using std::pair;
    using std::vector;
    using std::make_pair;
    using std::greater;
    
    struct Edge
    {
        int to,next,cost;
    }edge[2500001];
    int cnt,head[110005];
    
    void add_edge(int u,int v,int c=0)
    {
        edge[++cnt]=(Edge){v,head[u],c};
        head[u]=cnt;
    }
    
    int dis[110005];
    bool vis[110005];
    void Dijkstra(int s)
    {
        memset(dis,0x3f,sizeof(dis));
        dis[s]=0;
        priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > points;
        points.push(make_pair(0,s));
        while(!points.empty())
        {
            int u=points.top().second;
            points.pop();
            if(!vis[u])
            {
                vis[u]=1;
                for(int i=head[u];i;i=edge[i].next)
                {
                    int to=edge[i].to;
                    if(dis[to]>dis[u]+edge[i].cost) 
                    {
                        dis[to]=dis[u]+edge[i].cost;
                        points.push(make_pair(dis[to],to));
                    }
                }
            }
        }
    }
    
    int main()
    {
        int n=Read(),m=Read(),k=Read(),s=Read(),t=Read();
        int u,v,c;
        for(int i=0;i<m;++i)
        {
            u=Read(),v=Read(),c=Read();
            add_edge(u,v,c);
            add_edge(v,u,c);
            for(int j=1;j<=k;++j)
            {
                add_edge(u+(j-1)*n,v+j*n);
                add_edge(v+(j-1)*n,u+j*n);
                add_edge(u+j*n,v+j*n,c);
                add_edge(v+j*n,u+j*n,c);
            }
        }
        for(int i=1;i<=k;++i)
    	{
    		add_edge(t+(i-1)*n,t+i*n);
    	}//预防奇葩数据
        Dijkstra(s);
        printf("%d",dis[t+k*n]);
        return 0;
    }
    
    • 1

    信息

    ID
    3492
    时间
    1000ms
    内存
    125MiB
    难度
    4
    标签
    递交数
    0
    已通过
    0
    上传者