机房dalao推荐写的。。。(标签分层图)

经过前几题的分层图的洗礼,我深刻地体会到了分层图的优点和好处(主要是不想打dp....)

先说题吧....

很明确,模型是最短路,但是,怎么跑k个,是个问题....

解题过程:

1、先跑最短路,记录路径,然后找路径上的k条最长边,删掉

tips:贪心,很容易hack掉。

2、建两层的分层图(以前打的都是两层居多)

tips:会跑出0来....

solution:

主要就是:怎么连边喽....一开始老是卡住

连边有2种情况:

  1. 同一层之间的边,边权为题目给的边权,同层之间连
  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]飞行路线(分层图)的更多相关文章

  1. P4568 [JLOI2011]飞行路线 分层图

    题目描述 Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在nn个城市设有业务,设这些城市分别标记为00到n-1n−1,一共有mm种航线,每种航线连接两个城市,并且 ...

  2. P4568 [JLOI2011]飞行路线 分层图最短路

    思路:裸的分层图最短路 提交:1次 题解: 如思路 代码: #include<cstdio> #include<iostream> #include<cstring> ...

  3. bzoj2763: [JLOI2011]飞行路线(分层图spfa)

    2763: [JLOI2011]飞行路线 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3234  Solved: 1235[Submit][Stat ...

  4. bzoj 2763: [JLOI2011]飞行路线 -- 分层图最短路

    2763: [JLOI2011]飞行路线 Time Limit: 10 Sec  Memory Limit: 128 MB Description Alice和Bob现在要乘飞机旅行,他们选择了一家相 ...

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

    2763: [JLOI2011]飞行路线 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2523  Solved: 946[Submit][Statu ...

  6. [BZOJ2963][JLOI2011]飞行路线 分层图+spfa

    Description Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并 ...

  7. BZOJ2763: [JLOI2011]飞行路线(分层图 最短路)

    题意 题目链接 Sol 分层图+最短路 建\(k+1\)层图,对于边\((u, v, w)\),首先在本层内连边权为\(w\)的无向边,再各向下一层对应的节点连边权为\(0\)的有向边 如果是取最大最 ...

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

    题目描述 Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并且航线有一定的 ...

  9. bzoj 2763 [JLOI2011]飞行路线——分层图

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2763 分层图两种方法的练习. 1.把图分成k+1层,本层去上面一层的边免费.但空间时间都不算 ...

  10. bzoj2763 [JLOI2011]飞行路线——分层图

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2763 构建分层图. 代码如下: 写法1(空间略大)(时间很慢): #include<i ...

随机推荐

  1. 关于ajax提交表单的一些实例及遇到的问题和解决办法

    ajax提交的表单有两种情况: 第一种:input type类型没有file上传文件类型的表单 第二种:input type类型有file上传文件类型的表单 之所以分为两种:是因为原生ajax是不能提 ...

  2. python编程基础之二十七

    列表生成式:[exp for iter_var in iterable] 同样也会有字典生成式,集合生成式,没有元组生成式,元组生成式的语法被占用了 字典生成式,集合生成式,就是外面那个括号换成{}  ...

  3. GUI tkinter (pack、grid、place)布局篇

    """1.其实我们已经接触过 tkinter 的一种布局,就是 pack 布 局,它非常简单,我们不用做过多的设置,直接使用一个 pack 函数就可以了.2.grid 布 ...

  4. SVN部署(基于Linux)

    第一步:通过yum命令安装svnserve,命令如下: yum -y install subversion 此命令会全自动安装svn服务器相关服务和依赖,安装完成会自动停止命令运行 若需查看svn安装 ...

  5. 代码审计准备之Thinkphp3

    0x01环境部署: 下载: 获取ThinkPHP的方式很多,官方网站(http://thinkphp.cn)是最好的下载和文档获取来源. 官网提供了稳定版本的下载:http://thinkphp.cn ...

  6. swoole与php协程实现异步非阻塞IO开发

    “协程可以在遇到阻塞的时候中断主动让渡资源,调度程序选择其他的协程运行.从而实现非阻塞IO” 然而php是不支持原生协程的,遇到阻塞时如不交由异步进程来执行是没有任何意义的,代码还是同步执行的,如下所 ...

  7. selenium-find_element相关内容(2)

    find_element跟find_element_by_xxx的区别 1.查看文件D:\soft\python36\Lib\site-packages\selenium\webdriver\remo ...

  8. 在VM上安装OpenWrt

    1.选择'自定义',点击'下一步' 2.'硬件兼容性'默认,点击'下一步' 3.'稍后安装操作系统',点击'下一步' 4.客户机操作系统'Linux' 版本'CentOS 64位',点击'下一步' 说 ...

  9. 《如何学习基于ARM嵌入式系统》笔记整理

    author:Peong time:20190603 如何学习基于ARM嵌入式系统 一.嵌入式系统的概念 从硬件上讲,将外围器件,与CPU集成在一起. 从操作系统上讲,定制符合要求的系统内核 从应用上 ...

  10. Leetcode(9)回文数

    Leetcode(9)回文数 [题目表述]: 判断一个整数是否是回文数.回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数. 第一次:直接全部转 执行用时:148 ms: 内存消耗:13.4 ...