bzoj 2763 JLOI 2011 飞行路线 分层图+spfa

来源:互联网 发布:nodejs工程师 知乎 编辑:程序博客网 时间:2024/05/14 03:30

Description

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

Input

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

Output

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

分析

一个分层图。设f[i,j]为到达i点用了j次免费的最短路。ps:要把spfa的队列开大一些(8000000+)或者打循环队列。

代码

const  maxn=20000;  maxe=400000;type  arr=record    x,y:longint;    w:longint;    next:longint;end;var  n,m,nm,num:longint;  s,t:longint;  edge:array[0..maxe] of arr;  ls:array[0..maxn] of longint;  f:array[0..maxn,0..100] of longint;  queue:array[0..maxe*20,1..2] of longint;  status:array[0..maxn,0..100] of longint;procedure add(x,y,w:longint);begin  num:=num+1;  edge[num].x:=x;  edge[num].y:=y;  edge[num].w:=w;  edge[num].next:=ls[x];  ls[x]:=num;  num:=num+1;  edge[num].x:=y;  edge[num].y:=x;  edge[num].w:=w;  edge[num].next:=ls[y];  ls[y]:=num;end;procedure init;var  i:longint;  x,y,w:longint;begin  readln(n,m,nm);  readln(s,t);  num:=0;  for i:=1 to m do    begin      readln(x,y,w);      add(x,y,w);    end;end;procedure spfa;var  i,j,k:longint;  head,tail:longint;begin  fillchar(f,sizeof(f),$7f);  head:=0; tail:=1;  queue[1][1]:=s;  queue[1][2]:=0;  f[s][0]:=0;  status[s][0]:=1;  repeat    head:=head+1;    i:=ls[queue[head][1]];    while i<>0 do      begin        with edge[i] do          begin            j:=queue[head][2];            if f[x,j]+w<f[y,j]              then                begin                  f[y,j]:=f[x,j]+w;                  if status[y][j]=0                    then                      begin                        tail:=tail+1;                        queue[tail][1]:=y;                        queue[tail][2]:=j;                        status[y][j]:=1;                      end;                end;            if j<nm then              if f[x,j]<f[y,j+1]                then                  begin                    f[y,j+1]:=f[x,j];                    if status[y][j+1]=0                      then                        begin                          tail:=tail+1;                          queue[tail][1]:=y;                          queue[tail][2]:=j+1;                          status[y][j+1]:=1;                        end;                  end;            i:=next;          end;      end;    status[queue[head][1]][queue[head][2]]:=0;  until head=tail;end;procedure main;var  i,j,k:longint;  ans:longint;begin  spfa;  ans:=maxlongint;  for i:=0 to nm do    begin      if ans>f[t,i] then ans:=f[t,i];    end;  writeln(ans);end;begin  init;  main;end.
1 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 WS_CLIPCHILDREN设置键在哪里 数据结构(严蔚敏李冬梅)课后答案 ipz809 一个字包含的二进制位数 linux面试 【题目2】设计一个结构体类型,包含姓名、出生日期。其中出生日期又包含年、月、日三部分信息。输入n个好 【题目2】设计一个结构体类型,包含姓名、出生日期。其中出生日期又包含年、月、日三部分信息。输入n个好 结构体比较好友中年纪最小的 matlab三维矩阵可视化 使QQ崩溃 scanIP 按照规定,在高速公路上行使的机动车,达到或超出本车道限速的10%则处200元罚款;若达到或超出50% c语言输入三个数字 c语言如何输入三个数求平均值 c语言如何输入三个数求和 C语言为什么只录入了第一个数字 输入多个数字 c语言scanf只有第一个数字 scanf三个整数 double double类型 www和http 会计 日记账 myamnatfound IntroductiontoIoT IntroductiontoIoT 使用哪种类型的无线网络连接城市中的设备来创建城域网 傲世九重天绿帽版 节日 第一章《Java》的思维导图 《Java》的思维导图 python登录大华摄像机 2019普通高等学校招生全国统一考试诊断卷a 考前诊断卷 Travelingsalesmenofnhn.(theprestigiousKoreanintern www。qwer123。com Ubuntu --------------------------http://s.jiafeiyun.com/p getpid函数执行过程 增量模型