zoukankan      html  css  js  c++  java
  • BZOJ2763: [JLOI2011]飞行路线

    2763: [JLOI2011]飞行路线

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 2112  Solved: 802
    [Submit][Status][Discuss]

    Description

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

    Input

    数据的第一行有三个整数,n,m,k,分别表示城市数,航线数和免费乘坐次数。
    第二行有两个整数,s,t,分别表示他们出行的起点城市编号和终点城市编号。(0<=s,t<n)
    接下来有m行,每行三个整数,a,b,c,表示存在一种航线,能从城市a到达城市b,或从城市b到达城市a,价格为c。(0<=a,b<n,a与b不相等,0<=c<=1000)
     

    Output

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

    Sample Input

    5 6 1
    0 4
    0 1 5
    1 2 5
    2 3 5
    3 4 5
    2 3 3
    0 2 100

    Sample Output

    8

    HINT

    对于30%的数据,2<=n<=50,1<=m<=300,k=0;


    对于50%的数据,2<=n<=600,1<=m<=6000,0<=k<=1;


    对于100%的数据,2<=n<=10000,1<=m<=50000,0<=k<=10.



    显然有两种做法:

    S1:记dis[x][i]为为到了第x个点的并且用了i次免费机会的最小花费,直接最短路就可以了

    s2:将点拆分为n*(k+1) 个,构成分层图,每一点表示的是当前点用了k次免费的情况(如果x与y相连,就需要将x连向y的下一层)


     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstdlib>
     5 #include<vector>
     6 #include<cmath>
     7 #define llg long long 
     8 #define maxn 200010 
     9 using namespace std;
    10 vector <llg> a[maxn],val[maxn];
    11 llg i,j,k,x,n,m,y,f,t,z,dl[maxn*10],w,dis[maxn],tail,head,v;
    12 void link(llg x,llg y,llg z)
    13 {
    14      for (llg i=0;i<k;i++)
    15      {
    16          llg xx=x*(k+1)+i,yy=y*(k+1)+i;
    17          a[xx].push_back(yy+1),val[xx].push_back(0);
    18          a[yy].push_back(xx+1),val[yy].push_back(0);
    19          a[xx].push_back(yy),val[xx].push_back(z);
    20          a[yy].push_back(xx),val[yy].push_back(z);
    21      }
    22      llg i=k;
    23      llg xx=x*(k+1)+i,yy=y*(k+1)+i;
    24      a[xx].push_back(yy),val[xx].push_back(z);
    25      a[yy].push_back(xx),val[yy].push_back(z);
    26 }
    27 int main()
    28 {
    29    // freopen("a.in","r",stdin); freopen("a.out","w",stdout);
    30     cin>>n>>m>>k>>f>>t;
    31     n*=(k+1);
    32     for (i=1;i<=m;i++)
    33         {
    34           scanf("%lld%lld%lld",&x,&y,&z);
    35           link(x,y,z); 
    36         }
    37     tail=1; head=0;
    38     dl[1]=f*(k+1); for (i=0;i<=200001;i++) dis[i]=0x7fffffff; for (i=0;i<=k;i++) dis[f*(k+1)+i]=0;
    39     do{
    40        head++,head=(head-1)%1000000+1;
    41        x=dl[head];
    42        w=a[x].size();
    43        for (i=0;i<w;i++)
    44            {
    45             v=a[x][i];
    46             if (dis[v]>dis[x]+val[x][i])
    47             {
    48              dis[v]=dis[x]+val[x][i];
    49              tail++,tail=(tail-1)%1000000+1;
    50              dl[tail]=v;
    51             }
    52            }
    53     }while (head!=tail);
    54     llg ans=0x7fffffff;
    55     for (i=0;i<=k;i++) ans=min(ans,dis[t*(k+1)+i]);
    56     cout<<ans;
    57     return 0;
    58 } 
    本文作者:xrdog 作者博客:http://www.cnblogs.com/Dragon-Light/ 转载请注明出处,侵权必究,保留最终解释权!
  • 相关阅读:
    SCCM 补丁更新 失误排错一例
    Oracle 远程连接 DB配置 连接命令
    反向代理服务器
    用JMF播放音频 例子
    HTML css兼容
    Java国际化
    JBPM 之介绍,使用
    Nginx内核优化引用
    Nginx 学习
    局域网访问VMware虚拟机中的Ubuntu
  • 原文地址:https://www.cnblogs.com/Dragon-Light/p/5721340.html
Copyright © 2011-2022 走看看