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 ...
随机推荐
- slf4j+logback&logback.xml
添加maven依赖 <dependencies> <!--https://mvnrepository.com/artifact/org.slf4j/slf4j-api --> ...
- .Net Core AA.FrameWork应用框架介绍
开发多年,一直在从社区获取开源的便利,也深感社区力量的重要性,今天开源一个应用基础框架AA.FrameWork,也算是回馈社区,做出一点点贡献,希望能够帮助类似当年入行的我. AA.FrameWork ...
- Linux内存描述之内存节点node–Linux内存管理(二)
日期 内核版本 架构 作者 GitHub CSDN 2016-06-14 Linux-4.7 X86 & arm gatieme LinuxDeviceDrivers Linux内存管理 #1 ...
- margin和text-align实现水平居中的区别
1.首先text-align只应用于内联块和内联元素 text-align影响的是元素中的文本内容的对其方式(默认是left,设置为center时水平居中) 所以,将text-align设置为cent ...
- # Ubuntu16.04安装nvidia驱动+CUDA+cuDNN
Ubuntu16.04安装nvidia驱动+CUDA+cuDNN 准备工作 1.查看GPU是否支持CUDA lspci | grep -i nvidia 2.查看Linux版本 uname -m &a ...
- python编程基础之二十六
偏函数:当一个函数有大量的参数时候,调用时候非常不方便,于是就可以用偏函数解决,将一些参数固定(默认值),达到简化函数调用的目的 使用偏函数需要导入functools import functools ...
- Chrome插件开发(一)
作为一个开发人员,我们在日常工作中肯定会用到 Chrome 浏览器,同时也会用到谷歌的一些插件,比如 Tampermonkey,AdBlock等,在之前的文章本人还是用了 Tampermonkey,传 ...
- 安装高可用Hadoop生态 (三) 安装Hadoop
3. 安装Hadoop 3.1. 解压程序 ※ 3台服务器分别执行 .tar.gz -C/opt/cloud/packages /opt/cloud/bin/hadoop /etc/hadoop ...
- B站自动刷弹幕
B站自动填弹幕(附带createEvent消息机制) 昨晚看的比赛真的要气死我.RNG 居然又输了... 为了LPL...我写了一个为LPL加油的脚本.希望大家能和我一起为LPL加油! 脚本代码如下: ...
- Kali升级2018&&2019
0X01修改更新源 vim /etc/apt/sources.list #中科大 deb http://mirrors.ustc.edu.cn/kali kali-rolling main non-f ...