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

    题目描述

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

    输入

    数据的第一行有三个整数,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)
     

    输出

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

    样例输入

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

    样例输出

    8
    题解
    分层图最短路,拆点然后将乘坐免费航线的个数分层,跑spfa就行了。
     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<queue>
     5 #define maxn 10005
     6 #define inf 1<<29
     7 int head[maxn],vis[maxn][11],d[maxn][11];
     8 int ecnt,n,m,lim,s,t,ans=inf;
     9 using namespace std;
    10 struct edge{
    11     int u,v,w,next;
    12 }E[maxn*10];
    13 struct node{
    14     int u,num;
    15     node(int x,int y):u(x),num(y){}
    16 };
    17 void addedge(int u,int v,int w)
    18 {
    19     E[++ecnt].u=u;
    20     E[ecnt].v=v;
    21     E[ecnt].w=w;
    22     E[ecnt].next=head[u];
    23     head[u]=ecnt;
    24 }
    25 void spfa(int x)
    26 {
    27     queue<node> q;
    28     memset(d,127/3,sizeof(d));
    29     d[x][0]=0;
    30     node now(x,0);
    31     node next(0,0);
    32     q.push(now);
    33     vis[x][0]=1;
    34     while(!q.empty())
    35     {
    36         node now=q.front();q.pop();
    37         int dd=now.u;
    38         int k=now.num;
    39         vis[dd][k]=0;
    40         for(int i=head[dd] ; i ; i=E[i].next )
    41         {
    42             int v=E[i].v;
    43             int w=E[i].w;
    44             if(d[dd][k]+w<d[v][k])
    45             {
    46                 d[v][k]=d[dd][k]+w;
    47                 if(!vis[v][k])
    48                 {
    49                     vis[v][k]=1;
    50                     next.u=v;
    51                     next.num=k;
    52                     q.push(next);
    53                 }
    54             }
    55             if(d[dd][k]<d[v][k+1]&&k<lim)
    56             {
    57                 d[v][k+1]=d[dd][k];
    58                 if(!vis[v][k+1])
    59                 {
    60                     vis[v][k+1]=1;
    61                     next.u=v;
    62                     next.num=k+1;
    63                     q.push(next);
    64                 }
    65             }
    66         }
    67     }
    68     for(int i=0 ; i<=lim ; ++i)
    69         ans=min(ans,d[t][i]);
    70     printf("%d",ans);
    71 }
    72 int main()
    73 {
    74     int u,v,w;
    75     scanf("%d%d%d%d%d",&n,&m,&lim,&s,&t);
    76     for(int i=1 ; i<=m ; ++i )
    77     {
    78         scanf("%d%d%d",&u,&v,&w);
    79         addedge(u,v,w);
    80         addedge(v,u,w);
    81     }
    82     spfa(s);
    83     return 0;
    84 }
  • 相关阅读:
    文件权限---I
    python查看变量在内存中的地址
    Python3 基本数据类型
    print语法
    任务管理器启动项显示“没有可显示的启动项”如何解决?
    nginx 虚拟主机配置
    nginx 高级应用
    nginx 日志文件详解
    nginx 编译安装与配置使用
    python获取header脚本
  • 原文地址:https://www.cnblogs.com/fujudge/p/7496816.html
Copyright © 2011-2022 走看看