您的位置:首页 > 其它

【bzoj2763】[JLOI2011]飞行路线 分层图最短路

2017-02-28 19:44 369 查看
题目描述

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

dis[i][j]表示免费j条后i到s的最短路。

然后跑分层图Spfa。

第一次写分层图,也是第一次用pair,所以代码略丑,凑合着看吧。

#include <cstdio>
#include <cstring>
#include <queue>
#include <utility>
using namespace std;
queue<pair<int , int> > q;
int head[10010] , to[100010] , len[100010] , next[100010] , cnt , dis[10010][11] , inq[10010][11];
void add(int x , int y , int z)
{
to[++cnt] = y;
len[cnt] = z;
next[cnt] = head[x];
head[x] = cnt;
}
int main()
{
int n , m , k , i , s , t , x , y , z , ans = 0x3f3f3f3f;
pair<int , int> u;
scanf("%d%d%d%d%d" , &n , &m , &k , &s , &t);
for(i = 1 ; i <= m ; i ++ )
scanf("%d%d%d" , &x , &y , &z) , add(x , y , z) , add(y , x , z);
memset(dis , 0x3f , sizeof(dis));
dis[s][0] = 0;
q.push(make_pair(s , 0));
while(!q.empty())
{
u = q.front();
q.pop();
x = u.first , y = u.second;
inq[x][y] = 0;
for(i = head[x] ; i ; i = next[i])
{
if(dis[to[i]][y] > dis[x][y] + len[i])
{
dis[to[i]][y] = dis[x][y] + len[i];
if(!inq[to[i]][y]) inq[to[i]][y] = 1 , q.push(make_pair(to[i] , y));
}
if(y < k && dis[to[i]][y + 1] > dis[x][y])
{
dis[to[i]][y + 1] = dis[x][y];
if(!inq[to[i]][y + 1]) inq[to[i]][y + 1] = 1 , q.push(make_pair(to[i] , y + 1));
}
}
}
for(i = 0 ; i <= k ; i ++ ) ans = min(ans , dis[t][i]);
printf("%d\n" , ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: