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

    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.

    建立分层图。
    f[u][t]表示在节点u时已经免费乘坐t次的最少花
    费。照样跑最短路。
    枚举与u相连的所有节点v,w(u,v)表示权值。
    若t<k:
    f[v][t+1]=min(f[v][t+1],f[u][t])
    对于所有:
    f[v][t]=min(f[v][t],f[u][t]+w(u,v))

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<queue>
     6 using namespace std;
     7 struct Node
     8 {
     9   int next,to,dis;
    10 }edge[100001];
    11 struct XXX
    12 {
    13   int x;
    14   int k;
    15 };
    16 int num,head[100001],dist[100001][11],n,m,k,S,T,ans;
    17 bool vis[100001][11];
    18 void add(int u,int v,int d)
    19 {
    20   num++;
    21   edge[num].next=head[u];
    22   head[u]=num;
    23   edge[num].to=v;
    24   edge[num].dis=d;
    25 }
    26 void SPFA()
    27 {int i;
    28   queue<XXX> Q;
    29   Q.push((XXX){S,0});
    30   dist[S][0]=0;
    31   while (Q.empty()==0)
    32   {
    33     XXX u=Q.front();
    34     Q.pop();
    35     vis[u.x][u.k]=0;
    36     for (i=head[u.x];i;i=edge[i].next)
    37       {int v=edge[i].to;
    38     if (dist[v][u.k]>dist[u.x][u.k]+edge[i].dis)
    39       {
    40         dist[v][u.k]=dist[u.x][u.k]+edge[i].dis;
    41         if (vis[v][u.k]==0)
    42           {
    43         vis[v][u.k]=1;
    44         Q.push((XXX){v,u.k});
    45           }
    46       }
    47     if (u.k+1<=k&&dist[v][u.k+1]>dist[u.x][u.k])
    48       {
    49         dist[v][u.k+1]=dist[u.x][u.k];
    50         if (vis[v][u.k+1]==0)
    51           {
    52         vis[v][u.k+1]=1;
    53         Q.push((XXX){v,u.k+1});
    54           }
    55       }
    56       }
    57   }
    58 }
    59 int main()
    60 {int i,u,v,c;
    61   cin>>n>>m>>k;
    62   memset(dist,127/3,sizeof(dist));
    63   scanf("%d%d",&S,&T);
    64   for (i=1;i<=m;i++)
    65     {
    66       scanf("%d%d%d",&u,&v,&c);
    67       add(u,v,c);
    68       add(v,u,c);
    69     }
    70   SPFA();
    71   ans=2e9;
    72   for (i=0;i<=k;i++)
    73     ans=min(ans,dist[T][i]);
    74   cout<<ans;
    75 }
  • 相关阅读:
    常用的npm指令总结
    Mongoose基础
    2016总结与展望
    sleep与wait的区别
    查询平均分大于80分的学生
    求最大不重复子串
    快速排序
    按位与(&)运算的作用
    异或运算的作用
    java 字符串中的每个单词的倒序输出
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7473260.html
Copyright © 2011-2022 走看看