JLOI2011飞行路线

Posted tqr06

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JLOI2011飞行路线相关的知识,希望对你有一定的参考价值。

Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司
该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n - 1 
共有m种航线,每种航线连接两个城市,并且航线有一定的价格
Alice和Bob现在要从一个城市沿着航线到达另一个城市,途中可以进行转机
航空公司对他们这次旅行也推出优惠,他们可以免费在最多k:种航线上搭乘飞
那么Alice和Bob这次出行最少花费多少?

还是分层图的套路,有k种航线免费,就建k层,每往下一层就说明免费坐了一次航线
有一点很重要,分层图的题目空间一定要开够,不要像普通最短路那样看到点数就跑
还要考虑层数对使用空间的影响
水题,不多说了

代码:

#include<bits/stdc++.h>
#define N 1500005
using namespace std;

int n,m,k,s,t,u,v,w;

struct Edge
{
    int next,to,dis;
}edge[N<<1];
int cnt=1,head[N];

struct Node
{
    int u,dis;
    bool operator < (const Node &a) const
    {
        return a.dis<dis;
    }
};

inline void add_edge(int from,int to,int dis)
{
    edge[++cnt].next=head[from];
    edge[cnt].to=to;
    edge[cnt].dis=dis;
    head[from]=cnt;
}

int dis[N];
bool vis[N];
void Dijkstra(int s)
{
    memset(vis,0,sizeof(vis));
    memset(dis,0x3f,sizeof(dis));
    priority_queue<Node> q;
    q.push((Node){s,0});
    dis[s]=0;
    while(!q.empty())
    {
        int u=q.top().u;q.pop();
        if(vis[u]) continue;
        vis[u]=1;
        for(register int i=head[u];i;i=edge[i].next)
        {
            int v=edge[i].to;
            if(dis[v]>dis[u]+edge[i].dis)
            {
                dis[v]=dis[u]+edge[i].dis;
                if(!vis[v]) q.push((Node){v,dis[v]});
            }
        }
    }
}

template<class T>inline void read(T &res)
{
    char c;T flag=1;
    while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
    while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
}

int main()
{
    read(n);read(m);read(k);
    read(s);read(t);
    for(register int i=1;i<=m;++i)
    {
        read(u);read(v);read(w);
        for(register int j=0;j<=k;++j)
        {
            add_edge(u+j*n,v+j*n,w);
            add_edge(v+j*n,u+j*n,w);
        }
        for(register int j=0;j<k;++j)
        {
            add_edge(u+j*n,v+(j+1)*n,0);
            add_edge(v+j*n,u+(j+1)*n,0);
        }
    }
    for(register int i=0;i<k;++i) add_edge(t+i*n,t+(i+1)*n,0);
    Dijkstra(s);
    printf("%d
",dis[t+k*n]);
    return 0;
}

以上是关于JLOI2011飞行路线的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 2763 [JLOI2011]飞行路线

[BZOJ 2763][JLOI 2011] 飞行路线

BZOJ 2763: [JLOI2011]飞行路线

BZOJ 2763: [JLOI2011]飞行路线 spfa dp

Dijkstra BZOJ2763 [JLOI2011]飞行路线

bzoj 2763: [JLOI2011]飞行路线