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

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 2651  Solved: 1004

    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.

    Source

    最短路。

    分层图或DP。

    想象把平面图转化成立体结构,每条原有的<u,v>边从一层的u连到同一层或下一层的v,边权为原边权,同时有一条边从一层的u连到下一层的v,边权为0。

    起点是第0层的起点城市,终点是第k层的起点城市,跑最短路。

    ↑这样建边的效果是,在同一层内可以正常求最短路,而每使用一条“免费线路”,状态就会转移到下一层,这样保证最多使用k次免费线路。

    ——那么问题来了,这种算法确定无误,但是建边消耗内存太大了,怎么解决?

    ——不知道,我选择和评测机对刚。

    卡数据范围反复提交了6次终于AC了。

    [其实用DP思想做会更简单,不需要建k层图,只要dis状态开成二维就可以了]

     1 /*by SilverN*/
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<cstdio>
     6 #include<cmath>
     7 #include<vector>
     8 #include<queue>
     9 using namespace std;
    10 const int mxn=120010;
    11 int read(){
    12     int x=0,f=1;char ch=getchar();
    13     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    14     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    15     return x*f;
    16 }
    17 struct edge{
    18     int v,nxt;
    19     int dis;
    20 }e[2400000];
    21 int hd[mxn],mct=0;
    22 void add_edge(int u,int v,int dis){
    23     e[++mct].v=v;e[mct].nxt=hd[u];e[mct].dis=dis;hd[u]=mct;
    24     return;
    25 }
    26 int n,m,k;
    27 int ans;
    28 int dis[mxn];
    29 struct node{
    30     int v,dis;
    31     friend bool operator < (node a,node c){return a.dis>c.dis;}
    32 };
    33 priority_queue<node>q;
    34 int Dij(int st,int ed){
    35     memset(dis,0x3f,sizeof dis);
    36     dis[st]=0;
    37     q.push((node){st,0});
    38     int i,j;
    39     while(!q.empty()){
    40         node now=q.top();q.pop();
    41         if(dis[now.v]<now.dis)continue;
    42         int u=now.v;
    43         for(i=hd[u];i;i=e[i].nxt){
    44             int v=e[i].v;
    45             if(dis[v]>dis[u]+e[i].dis){
    46                 dis[v]=dis[u]+e[i].dis;
    47                 q.push((node){v,dis[v]});
    48             }
    49         }
    50     }
    51     return dis[ed+k*n];
    52 }
    53 int main(){
    54     n=read();m=read();k=read();
    55     int i,j;
    56     int s=read()+1,t=read()+1;
    57     int u,v,d;
    58     for(i=1;i<=m;i++){
    59         u=read()+1;v=read()+1;d=read();
    60         for(j=0;j<=k;j++){
    61             add_edge(u+j*n,v+j*n,d);
    62             add_edge(v+j*n,u+j*n,d);
    63             if(j<k){
    64                 add_edge(u+j*n,v+j*n+n,0);
    65                 add_edge(v+j*n,u+j*n+n,0);
    66             }
    67         }
    68     }
    69     int ans=Dij(s,t);
    70 //  for(i=1;i<=n*k+n;i++)printf("%d
    ",dis[i]);
    71     printf("%d
    ",ans);
    72     return 0;
    73 }
  • 相关阅读:
    [转]DllMain中不当操作导致死锁问题的分析——DllMain中要谨慎写代码(完结篇)
    【机器学习】深入理解人工神经网络结构
    【机器学习】初识人工神经网络
    【机器学习】通过正则化解决过拟合问题
    【机器学习】逻辑回归
    【机器学习】用Octave实现一元线性回归的梯度下降算法
    【机器学习】对梯度下降算法的进一步理解
    【机器学习】从分类问题区别机器学习类型 与 初步介绍无监督学习算法 PAC
    【机器学习】感知机学习算法(PLA)
    【机器学习】1 监督学习应用与梯度下降
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6109488.html
Copyright © 2011-2022 走看看