• 「JLOI2011」「LuoguP4568」飞行路线(分层图最短路


    题目描述

    Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司。该航空公司一共在nn个城市设有业务,设这些城市分别标记为00到n-1n1,一共有mm种航线,每种航线连接两个城市,并且航线有一定的价格。

    Alice和Bob现在要从一个城市沿着航线到达另一个城市,途中可以进行转机。航空公司对他们这次旅行也推出优惠,他们可以免费在最多kk种航线上搭乘飞机。那么Alice和Bob这次出行最少花费多少?

    输入输出格式

    输入格式:

    数据的第一行有三个整数,n,m,kn,m,k,分别表示城市数,航线数和免费乘坐次数。
    第二行有两个整数,s,ts,t,分别表示他们出行的起点城市编号和终点城市编号。
    接下来有m行,每行三个整数,a,b,ca,b,c,表示存在一种航线,能从城市aa到达城市bb,或从城市bb到达城市aa,价格为cc。

    输出格式:

    只有一行,包含一个整数,为最少花费。

    输入输出样例

    输入样例#1: 复制
    5 6 1
    0 4
    0 1 5
    1 2 5
    2 3 5
    3 4 5
    2 3 3
    0 2 100
    输出样例#1: 复制
    8

    说明

    对于30%的数据,2 le n le 50,1 le m le 300,k=02n50,1m300,k=0;
    对于50%的数据,2 le n le 600,1 le m le 6000,0 le k le 12n600,1m6000,0k1;
    对于100%的数据,2 le n le 10000,1 le m le 50000,0 le k le 102n10000,1m50000,0k10,0 le s,t<n,0 le a,b<n,a eq b,0 le c le 10000s,t<n,0a,b<n,ab,0c1000

    题解

    把原图建k+1层,其中第i层表示用掉了(i-1)次免费票的旅程。

    对于每条边,再在相邻一层的方向建免费边。(原图:$u→v$;免费边:$u_{第i层}→v_{第(i+1)层}$)

    然后从第一层的$s$跑到第(k+1)层的$t$就好了。

    感觉这个图建的非常有网络流的感觉呢。

     1  qwerta 
     2 P4568 [JLOI2011]飞行路线 Accepted 
     3 100
     4 代码 C++,1.24KB
     5 提交时间 2018-11-02 19:35:30
     6 耗时/内存 617ms, 26264KB
     7 #include<iostream>
     8 #include<cstring>
     9 #include<cstdio>
    10 #include<queue>
    11 using namespace std;
    12 const int MAXN=10000+3,MAXM=50000+3;
    13 struct emm{
    14     int e,f,l;
    15 }a[11*4*MAXM];
    16 int h[11*MAXN];
    17 int tot=0;
    18 int n,k;
    19 void con(int x,int y,int l)
    20 {
    21     //cout<<"con "<<x<<" "<<y<<" "<<l<<endl;
    22     a[++tot].f=h[x];
    23     h[x]=tot;
    24     a[tot].e=y;
    25     a[tot].l=l;
    26     return;
    27 }
    28 void add(int x,int y,int l)
    29 {
    30     for(int c=0;c<=k;++c)
    31     {
    32         int u=x+c*n,v=y+c*n;
    33         con(u,v,l);
    34         con(v,u,l);
    35     }
    36     for(int c=0;c<k;++c)
    37     {
    38         int u=x+c*n,v=y+(c+1)*n;
    39         con(u,v,0);
    40         u=x+(c+1)*n,v=y+c*n;
    41         con(v,u,0);
    42     }
    43 }
    44 struct ahh{
    45     int nod,v;
    46 };
    47 struct cmp{
    48     bool operator()(ahh qaq,ahh qwq){
    49         return qaq.v>qwq.v;
    50     };
    51 };
    52 priority_queue<ahh,vector<ahh>,cmp>q;
    53 int d[11*MAXN];
    54 bool sf[11*MAXN];
    55 int main()
    56 {
    57     //freopen("a.in","r",stdin);
    58     int m;
    59     scanf("%d%d%d",&n,&m,&k);
    60     int s,t;
    61     scanf("%d%d",&s,&t);
    62     for(int i=1;i<=m;++i)
    63     {
    64         int x,y,l;
    65         scanf("%d%d%d",&x,&y,&l);
    66         add(x,y,l);
    67     }
    68     t=k*n+t;
    69     //cout<<s<<" "<<t<<endl;
    70     memset(d,127,sizeof(d));
    71     d[s]=0;
    72     q.push((ahh){s,0});
    73     while(!q.empty())
    74     {
    75         int x;
    76         do{x=q.top().nod;q.pop();}while(sf[x]&&!q.empty());
    77         sf[x]=1;
    78         for(int i=h[x];i;i=a[i].f)
    79         if(d[a[i].e]>d[x]+a[i].l)
    80         {
    81             d[a[i].e]=d[x]+a[i].l;
    82             q.push((ahh){a[i].e,d[a[i].e]});
    83         }
    84     }
    85     cout<<d[t];
    86     return 0;
    87 }
  • 相关阅读:
    [LOJ#6284.数列分块入门8] ODT(珂朵莉树)解法
    [CF Contest] Sum of Round Numbers 题解
    基础数论记录
    [CF Contest] Kana and Dragon Quest game 题解
    hexo上怎么写博客
    keepalived的部署
    python局部和全局变量
    python发送邮件
    lamp架构的部署
    rayns数据同步
  • 原文地址:https://www.cnblogs.com/qwerta/p/9898832.html
Copyright © 2020-2023  润新知