zoukankan      html  css  js  c++  java
  • [USACO09FEB] 改造路Revamping Trails | [JLOI2011] 飞行路线

    题目链接:

    改造路

    飞行路线

    其实这两道题基本上是一样的,就是分层图的套路题。

    为什么是分层图呢?首先,我们的选择次数比较少,可以把这几层的图建出来而不会爆空间。然后因为选择一个边权为0的路线之后我们就进入了下一个状态,最短路的计算就和不选择这个边权为0的路线完全独立了。

    所以我们把每一层的图建出来,相邻图有边的话连0边,其他的按照原样连。dis数组存最短路。(最后答案就是dis[n*k+end]),end为终点。

    所以所以。。。也没有什么可说的???

    注意要写dij,以后图论的题能不写spfa就别写。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<vector>
    #define MAXM 4100000
    #define MAXN 410000
    using namespace std;
    bool done[MAXN];
    int n,m,edge_number,st,end,k;
    int dis[MAXN],head[MAXN];
    struct Edge{int nxt,to,dis;}edge[MAXM];
    struct Node{
        int u,d;
        friend bool operator <(struct Node x,struct Node y)
        {
            return x.d>y.d;
        }
    };
    void add(int from,int to,int dis)
    {
        edge[++edge_number].dis=dis;
        edge[edge_number].to=to;
        edge[edge_number].nxt=head[from];
        head[from]=edge_number;
    }
    inline void dij()
    {
        priority_queue<Node>q;
        memset(dis,0x3f,sizeof(dis));
        q.push((Node){st,0});
        dis[st]=0;
        while(!q.empty())
        {
            int u=q.top().u;
            q.pop();
            if(done[u]) continue;
            done[u]=1;
            for(int i=head[u];i;i=edge[i].nxt)
            {
                int v=edge[i].to;
                if(dis[v]>dis[u]+edge[i].dis)
                {
                    dis[v]=dis[u]+edge[i].dis;
                    q.push((Node){v,dis[v]});
                }
            }
        }
    }
    int main()
    {
    
        scanf("%d%d%d",&n,&m,&k);
        st=1,end=n;
        for(int i=1;i<=m;i++)
        {
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            add(u,v,w);
            add(v,u,w);
            for(int j=1;j<=k;j++)
            {
                add(u+(j-1)*n,v+j*n,0);
                add(v+(j-1)*n,u+j*n,0);
                add(u+j*n,v+j*n,w);
                add(v+j*n,u+j*n,w);
            }
        }
        for(int i=1;i<=k;i++)
            add((i-1)*n+end,i*n+end,0);
        dij();
        printf("%d
    ",dis[n*k+end]);
        return 0;
    }
    
  • 相关阅读:
    UVA
    计算几何 点和线
    CTU Open Contest 2017
    2018 Multi-University Training Contest 2
    2018 Multi-University Training Contest 1
    Nordic Collegiate Programming Contest (NCPC) 2016
    The 2016 ACM-ICPC Asia Shenyang Regional Contest
    The 2016 ACM-ICPC Asia Qingdao Regional Contest
    CCPC 2016-2017, Finals
    North American Invitational Programming Contest (NAIPC) 2016
  • 原文地址:https://www.cnblogs.com/fengxunling/p/9870871.html
Copyright © 2011-2022 走看看