zoukankan      html  css  js  c++  java
  • 洛谷 4568 [JLOI2011] 飞行路线

    题目戳这里
    一句话题意:


    有n个点,m条边的有向图,最多可以把k条边变为0,求从起点到终点最短距离。


    Solution


    首先看到这题目,感觉贼难,看起来像DP,貌似也有大佬这么做,但鉴于本蒟蒻思维能力有限,经过大佬点拨后拿出了失传已久的绝技——分层图!(废话真多).
    那么我们就可以愉快地建图了,根据题意,建出k+1层图,每条边从上一层到下一层的边权为0,每次从一层到下一层,就相当于用了一次0边,从0层起点到k层终点,正好用了k次。另外需要注意的是,因为边数太多,裸的SPFA会被卡。


    Coding

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 1e5;
    struct road
    {
        int to,next,w;
    }e[N*50+5];
    int n,m,s,t,head[N*10+5],cnt,k;
    inline int read()
    {
        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-'0',ch=getchar();
        return X*w;
    }
    void add(int x,int y,int w)
    {
        cnt++;
        e[cnt].w=w;
        e[cnt].to=y;
        e[cnt].next=head[x];
        head[x]=cnt;
    }
    int vis[N*10+5],dis[N*10+5];
    void Dijkstra()
    {
        memset(dis,0x3f,sizeof(dis));
        dis[s]=0;
        priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > q;
        q.push(make_pair(0,s));
        while(!q.empty())
        {
            int u=q.top().second;
            q.pop();
            if(!vis[u])
            {
                vis[u]=1;
                for(int i=head[u];i;i=e[i].next)
                {
                    int v=e[i].to;
                    if(dis[v]>dis[u]+e[i].w) 
                    {
                        dis[v]=dis[u]+e[i].w;
                        q.push(make_pair(dis[v],v));
                    }
                }
            }
        }
    }
    int main()
    {
        cin>>n>>m>>k>>s>>t;
        s++,t++;
        for(int i=1;i<=m;i++)
        {
            int u,v,w;
            u=read(),v=read(),w=read();
            u++,v++;
            for(int j=0;j<=k;j++)
            {
                add(u+j*n,v+j*n,w);
                add(v+j*n,u+j*n,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);
            }
        }
        for(int i=1;i<=k;i++)
            add(t+(i-1)*n,t+i*n,0);
        Dijkstra();
        cout<<dis[t+k*n];
        return 0;
    }
    
  • 相关阅读:
    CSS实现的几款不错的菜单栏
    成长经历之新年感触
    Jquery实现的几款漂亮的时间轴
    一些常用的前端基础操作
    数据图表插件echarts(二)
    数据图表插件Echarts(一)
    jQuery的属性
    jQuery的61种选择器
    JavaScript基础知识总结(四)
    JavaScript基础知识总结(三)
  • 原文地址:https://www.cnblogs.com/Le-mon/p/9520225.html
Copyright © 2011-2022 走看看