P4568 [JLOI2011]飞行路线(分层图)

机房dalao推荐写的。。。(标签分层图)
经过前几题的分层图的洗礼,我深刻地体会到了分层图的优点和好处(主要是不想打dp....)
先说题吧....
很明确,模型是最短路,但是,怎么跑k个,是个问题....
解题过程:
1、先跑最短路,记录路径,然后找路径上的k条最长边,删掉
tips:贪心,很容易hack掉。
2、建两层的分层图(以前打的都是两层居多)
tips:会跑出0来....
solution:
主要就是:怎么连边喽....一开始老是卡住
连边有2种情况:
- 同一层之间的边,边权为题目给的边权,同层之间连
- 层与层之间,一个点连到下一层的它对应的出点,边权为0,为单向边
一共K层,上层可以跑到下层的出点,却不能回去,这就是一次免票。
然后跑最短路,最后查t+n*k那个点的dis就可以了。
for(int i=;i<=m;i++)
{
int x,y,z;
x=read();y=read();z=read();
addedge(x,y,z);
addedge(y,x,z);
for(int j=;j<=k;j++)
{
addedge(x+n*j,y+n*j,z);
addedge(y+n*j,x+n*j,z);
addedge(x+(j-)*n,y+j*n,);
addedge(y+(j-)*n,x+j*n,);
}
}
如上,分层连边。
之后就是一个spfa的事了(然而我各种常数(畜生)优化+O2卡到比旁边dalao快600ms的地步哈哈哈哈)
值得注意:
1、最后要把每一层的t点连在一起,因为如果在第二层就跑到了最短,在最后一层的t并不能查到正确答案
2、一共有k+1层,所以初始化dis要k+1层,因为这个卡了一小会...
#include<bits/stdc++.h>
using namespace std;
const int maxn=6e6+;
int n,m,k;
int s,t;
inline int read()
{
int x=,f=;char s=getchar();
while(s>''||s<''){if(s=='-')f=-;s=getchar();}
while(s<=''&&s>=''){x=x*+s-'';s=getchar();}
return x*f;
}
struct edge
{
int to,next,dis;
}e[maxn];
int head[maxn],cnt;
inline void addedge(int from,int to,int dis)
{
e[++cnt].next=head[from];
e[cnt].to=to;
e[cnt].dis=dis;
head[from]=cnt;
}
int dis[maxn],vis[maxn];
struct cmp
{
bool operator () (int a,int b)
{
return dis[a]>dis[b];
}
};
priority_queue < int , vector < int > , cmp > q;
//queue < int > q;
void spfa(int s)
{ for(int i=;i<=(k+)*n;i++)
{
dis[i]=;
vis[i]=;
}
//memset(dis,0x3f,sizeof(dis));
q.push(s);
dis[s]=;
vis[s]=;
while(!q.empty())
{
//cout<<233;
int u=q.top();
//int u=q.front();
q.pop();
vis[u]=;
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].to;
if(dis[v]>dis[u]+e[i].dis)
{
dis[v]=dis[u]+e[i].dis;
if(vis[v]==)
{
q.push(v);
vis[v]=;
}
}
}
}
}
int main()
{
n=read();
m=read();
k=read();
s=read();
t=read();
for(int i=;i<=m;i++)
{
int x,y,z;
x=read();
y=read();
z=read();
addedge(x,y,z);
addedge(y,x,z);
for(int j=;j<=k;j++)
{
addedge(x+n*j,y+n*j,z);
addedge(y+n*j,x+n*j,z);
addedge(x+(j-)*n,y+j*n,);
addedge(y+(j-)*n,x+j*n,);
}
}
for(int i=;i<=k;i++)
addedge(t+(i-)*n,t+i*n,);
spfa(s);
cout<<dis[t+k*n];//printf("%d",dis[t+k*n]);
return ;
}
现在来说一说dp和分层图的关系:
首先,分层图的“层”是什么,它就是dp中的状态。在一些图论题目中,状态不好转移,就可以使用分层图进行转移,不需要再管“从哪转移”这个问题,剩下的最优解直接交给spfa就行了。(最优贸易)
这些状态之间可以互相转移,一般在二维或是以上,可以省去一些不相关状态的枚举,但是因为spfa的广泛枚举性还是会枚举更多“不是最优解”的状态的。
(完)
P4568 [JLOI2011]飞行路线(分层图)的更多相关文章
- P4568 [JLOI2011]飞行路线 分层图
题目描述 Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在nn个城市设有业务,设这些城市分别标记为00到n-1n−1,一共有mm种航线,每种航线连接两个城市,并且 ...
- P4568 [JLOI2011]飞行路线 分层图最短路
思路:裸的分层图最短路 提交:1次 题解: 如思路 代码: #include<cstdio> #include<iostream> #include<cstring> ...
- bzoj2763: [JLOI2011]飞行路线(分层图spfa)
2763: [JLOI2011]飞行路线 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3234 Solved: 1235[Submit][Stat ...
- bzoj 2763: [JLOI2011]飞行路线 -- 分层图最短路
2763: [JLOI2011]飞行路线 Time Limit: 10 Sec Memory Limit: 128 MB Description Alice和Bob现在要乘飞机旅行,他们选择了一家相 ...
- BZOJ2763[JLOI2011]飞行路线 [分层图最短路]
2763: [JLOI2011]飞行路线 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2523 Solved: 946[Submit][Statu ...
- [BZOJ2963][JLOI2011]飞行路线 分层图+spfa
Description Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并 ...
- BZOJ2763: [JLOI2011]飞行路线(分层图 最短路)
题意 题目链接 Sol 分层图+最短路 建\(k+1\)层图,对于边\((u, v, w)\),首先在本层内连边权为\(w\)的无向边,再各向下一层对应的节点连边权为\(0\)的有向边 如果是取最大最 ...
- 【bzoj2763】[JLOI2011]飞行路线 分层图最短路
题目描述 Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并且航线有一定的 ...
- bzoj 2763 [JLOI2011]飞行路线——分层图
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2763 分层图两种方法的练习. 1.把图分成k+1层,本层去上面一层的边免费.但空间时间都不算 ...
- bzoj2763 [JLOI2011]飞行路线——分层图
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2763 构建分层图. 代码如下: 写法1(空间略大)(时间很慢): #include<i ...
随机推荐
- idea快捷键(mac下)
ctrl+/ 代码提示 command+o 搜索要进入的类并进入 command+shift+enter 另起一行 command+shift+u 在变成全大写与变成全小写之间切换 shift+鼠标滑 ...
- 直通BAT面试题库锦集
01 python面试题(汇总) 02 面向对象 03 网络和并发编程 04 模块 05 设计模式 06 前端 07 Django框架 08 Flask 09 tornado 10 DB
- 浅谈分布式事务与TX-LCN
最近做项目使用到了分布式事务,下面这篇文章将给大家介绍一下对分布式事务的一些见解,并讲解分布式事务处理框架TX-LCN的执行原理,初学入门,错误之处望各位不吝指正. 什么情况下需要使用分布式事务? 使 ...
- mongodb完整安装
在线下载安装依赖包 yum -y install gcc gcc-c++ yum -y install gcc gcc-c++ ncurses ncurses-devel cmake bison yu ...
- Js获取宽高度的归纳集锦总结
首先,先吓唬一下我们的小白们!在js中的描述宽高的可以细分有22种.属性根据不同的兼容性也分为五种 window.innerWidth //除去菜单栏的窗口宽度,与浏览器相关 window.inner ...
- Anrlr4 生成C++版本的语法解析器
一. 写在前面 我最早是在2005年,首次在实际开发中实现语法解析器,当时调研了Yacc&Lex,觉得风格不是太好,关键当时yacc对多线程也支持的不太好,接着就又学习了Bison&F ...
- RF读取excel
pip install robotframework-ExcelLibrary (安装ExcelLibrary库) 关键字: Open Excel 打开excel Get Column Count 获 ...
- 使用AddLayer方法加载shp文件中使用的Map、Dataset等对象详解
内容源自:ArcGIS Engine+C#入门经典 方法二:使用axMapControl1对象的AddLayer方法加载ShapeFile文件 添加ShapeFile文件需要用到Map.Dataset ...
- Java编程思想——第17章 容器深入研究 读书笔记(二)
五.List的功能方法 排除Collection已包含的方法外还增加了 boolean addAll(int index, Collection<? extends E> c);从索引位置 ...
- [LUOGU1272] 重建道路 - 树形背包
题目描述 一场可怕的地震后,人们用N个牲口棚(1≤N≤150,编号1..N)重建了农夫John的牧场.由于人们没有时间建设多余的道路,所以现在从一个牲口棚到另一个牲口棚的道路是惟一的.因此,牧场运输系 ...