您的位置:首页 > 其它

[BZOJ2763][JLOI2011][分层图最短路]飞行路线

2014-04-22 13:52 363 查看
<题目>

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

<算法>

分层图最短路 堆优化的Dijkstra

<分析>

乍一看是最短路,再仔细一看用最短路似乎无法实现。分层图可以很巧妙的解决这个问题。想象你每次使用免费航线之前和之后分别存在于不同的时空(不同的层)里面,每使用一次免费航线,你就从这个时空进入了另一个时空(免费)。根据以上思想建图,一共建k+1层图,相邻的两层图中进行连边(单向边,距离为1)。然后跑dijkstra即可

<注意>

分层图思想~

spfa会超时。我用的是stl里面的priority_queue写堆j。注意priority_queue里面不用front()而是top。而且需要重定义结构体的operator<

<鸣谢>

感谢zky的题解

<代码>

/**************************************************************
Problem: 2763
User: gaotianyu1350
Language: C++
Result: Accepted
Time:512 ms
Memory:38320 kb
****************************************************************/

#include
#include
#include
#include
#include
#include
using namespace std;

#define MAXNODE 200100
#define MAXEDGE 3000000
#define INF     1000000000

struct Node
{
int dis,u;
bool operator<(const Node x)const
{
return dis>x.dis;
}
};

int point[MAXNODE]={0},w[MAXEDGE],next[MAXEDGE]={0},v[MAXEDGE],tot;
int dis[MAXNODE];
bool check[MAXNODE];
priority_queue q;

int n,m,k;

void addedge(int x,int y,int cost)
{
tot++;
next[tot]=point[x];point[x]=tot;v[tot]=y;w[tot]=cost;
}

int dijkstra(int s,int t)
{
memset(dis,0x7f,sizeof(dis));
memset(check,0,sizeof(check));
while (!q.empty()) q.pop();
dis[s]=0;q.push((Node){0,s});
while (!q.empty())
{
Node now=q.top();q.pop();
if (check[now.u]) continue;
check[now.u]=true;
for (int temp=point[now.u];temp;temp=next[temp])
if (dis[now.u]+w[temp]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  BZOJ JLOI 分层图