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

    2763: [JLOI2011]飞行路线

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 3089  Solved: 1158
    [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.


    Source

    k很小,所以这显然是个分层图,有一个很类似的题——bzoj1614,但感觉很不一样,烧脑

    sdfzgzk说可以只加两条边,然而蒟蒻的我没有听懂,所以只好推一个边数的大约上界去开数组了

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<queue>
     6 using namespace std;
     7 int n,m,k,s,e,cnt,ans;
     8 struct data{
     9     int next,to,dis;
    10 }edge[2500010];
    11 struct node{
    12     int x,dd;
    13 };
    14 int head[1250010],w[1250010];
    15 bool check[1250010];
    16 priority_queue<node>q;
    17 void add(int start,int end,int d){
    18     edge[++cnt].next=head[start];
    19     edge[cnt].to=end;
    20     edge[cnt].dis=d;
    21     head[start]=cnt;
    22 }
    23 bool operator<(node aa,node bb){
    24     if(aa.dd==bb.dd) return aa.x<bb.x;
    25     return aa.dd>bb.dd;
    26 }
    27 void dijkstra(){
    28     memset(w,0x3f3f3f3f,sizeof(w));
    29     q.push((node){s,0});
    30     w[s]=0;
    31     while(!q.empty()){
    32         node tmp=q.top();
    33         q.pop();
    34         if(check[tmp.x]) continue;
    35         check[tmp.x]=1;
    36         for(int i=head[tmp.x];i;i=edge[i].next)
    37             if(w[edge[i].to]>w[tmp.x]+edge[i].dis){
    38                 w[edge[i].to]=w[tmp.x]+edge[i].dis;
    39                 q.push((node){edge[i].to,w[edge[i].to]});
    40             }
    41     }
    42 }
    43 int main(){
    44     scanf("%d%d%d%d%d",&n,&m,&k,&s,&e);
    45     int x=0,y=0,z=0;
    46     for(int i=1;i<=m;i++){
    47         scanf("%d%d%d",&x,&y,&z);
    48         for(int j=0;j<=k;j++){
    49             add(x+j*n,y+j*n,z);
    50             add(y+j*n,x+j*n,z);
    51             if(j<k){
    52                 add(x+j*n,y+(j+1)*n,0);
    53                 add(y+j*n,x+(j+1)*n,0);
    54             }
    55         }
    56     }
    57     dijkstra();
    58     ans=0x3f3f3f3f;
    59     for(int i=0;i<=k;i++) ans=min(ans,w[e+i*n]);
    60     printf("%d
    ",ans);
    61     return 0;
    62 }
  • 相关阅读:
    sed命令用法详解
    Linux date命令的用法
    安装oracle客户端连接工具
    nginx安装
    orabbix监控oracle数据库
    Oracle数据库修改用户密码
    oracle数据库重启操作
    centos6.5安装oracle11.2.0.1.0数据库
    教你几招解决电脑假死现象
    (java实现)杭电oj 2097 Sky数
  • 原文地址:https://www.cnblogs.com/zwube/p/7077616.html
Copyright © 2011-2022 走看看