【Heap-dijkstra】CDOJ1639 云中谁寄锦书来?雁字回时,月满西楼。
题意: 在n个点m条边的无向图上,有k个出口 从起点出发,每到一个点(包括起点),该点连出的边中有d条会被封锁 求最坏情况下到达出口的最短路
题解: 该题为dijkstra算法的拓展
由于求最坏情况下的最短路,对于每个点,显然最优的前d条边不能走
对于边u->v,必然要先得到v到出口的最坏情况下的最短路 才能得到u经过该边再到出口的最坏情况下的最短路,也就是该边对于u的价值 所以要从出口往回考虑
令f[i]表示i到出口的最坏情况下的最短路 同dijkstra算法一样,每个点i可以分为f[i]已确定的和f[i]未确定的 初始时自然是对于每个出口x,f[x]=0已确定
对于f[v]已确定的点v,将边权为w的边u->v以f[v]+w为关键字加入小根堆中
对于每个点i还要记录cnt[i]=k,表示到i后,i连出的最优的前k条边已被封锁
每次取出堆顶对应的边u->v(若f[u]已确定直接弹出) 则该边为u连出的(除已被封锁的边外)最优的边 若cnt[u]<d,该边必然会被封锁,那么将cnt[u]加1,弹出堆顶 若cnt[u]=d,那么可以确定f[u]=f[v]+w,再用u更新连向u的边,弹出堆顶
重复这一过程直到确定f[0]的值,该值即为答案
不妨思考下为何不从起点开始考虑
若从起点开始考虑,令f[i]表示从起点到i的最坏情况下的最短路 对于f[u]已确定的点u,将边权为w的边u->v以f[u]+w为关键字加入小根堆中 每次取出堆顶对应的边u->v(若f[v]已确定直接弹出) 若cnt[u]<d,该边必然会被封锁,那么将cnt[u]加1,弹出堆顶 若cnt[u]=d,可以确定f[v]=f[u]+w,再用v更新v连向的边,弹出堆顶
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
struct Edge{
int u,v,d;
};
bool operator < (const Edge &a,const Edge &b){
return a.d>b.d;
}
priority_queue<Edge>Heap;
int n,m,K,d,f[100010],cnts[100010];
int v[2000010],__next[2000010],first[100010],w[2000010],e;
void AddEdge(int U,int V,int W){
v[++e]=V;
w[e]=W;
__next[e]=first[U];
first[U]=e;
}
int main(){
int x,y,z;
scanf("%d%d%d%d",&n,&m,&K,&d);
for(int i=1;i<=m;++i){
scanf("%d%d%d",&x,&y,&z);
AddEdge(x,y,z);
AddEdge(y,x,z);
}
memset(f,0x7f,sizeof(f));
for(int i=1;i<=K;++i){
scanf("%d",&x);
f[x]=0;
cnts[x]=d+1;
for(int j=first[x];j;j=__next[j]){
Heap.push((Edge){v[j],x,w[j]});
}
}
while(!Heap.empty()){
Edge E=Heap.top(); Heap.pop();
++cnts[E.u];
if(cnts[E.u]==d+1){
f[E.u]=E.d;
for(int i=first[E.u];i;i=__next[i]){
if(cnts[v[i]]<=d){
Heap.push((Edge){v[i],E.u,f[E.u]+w[i]});
}
}
}
}
printf("%d\n",f[0]>2000000000 ? -1 : f[0]);
return 0;
}
【Heap-dijkstra】CDOJ1639 云中谁寄锦书来?雁字回时,月满西楼。的更多相关文章
- 阿里云鼠标垫,云中谁寄锦书来,阿里云定制GIT指令集鼠标垫
活动地址 云中谁寄锦书来 活动时间 2020.8.19-8.28 奖品 必得,每日200份,共2000份 参考答案 tips:单选选择以上都是,多选就是全选 云效DevOps包含哪些产品- ABCDE ...
- [POJ3463] Sightseeing(次短路 Heap + Dijkstra)
传送门 用dijkstra比较好,spfa可能有的重复 dis[x][2]:dis[x][0]表示起点到x的最短路.dis[x][1]表示起点到x的次短路: tot[x][2]:tot[x][0]表示 ...
- Radix Heap ---Dijkstra算法的优化 BY Gremount
Radix Heap 算法是在Dijkstra的Dial实现的基础上,通过减少对桶的使用,来优化算法的时间复杂度: Dial 时间复杂度是O(m+nC) -------C是最长的链路 Radi ...
- 【 D3.js 高级系列 — 1.0 】 文本的换行
在 SVG 中添加文本是使用 text 元素.但是,这个元素不能够自动换行,超出的部分就显示不出来了,怎么办呢? 高级系列开篇前言 从今天开始写高级系列教程.还是那句话,由于本人实力有限,不一定保证入 ...
- CodeForces 【20C】Dijkstra?
解题思路 heap+Dijkstra就能过.注意边是双向边,要用long long. 附上代码 #include <iostream> #include <queue> #in ...
- HTML第二天学习笔记
今天看视频学习的第一个知识是HTML中的块元素<div>和行内元素<span>. <!doctype html> <html lang="en&qu ...
- poj分类 很好很有层次感。
初期: 一.基本算法: (1)枚举. (poj1753,poj2965) (2)贪心(poj1328,poj2109,poj2586) (3)递归和分治法. ( ...
- 【转】POJ题目分类推荐 (很好很有层次感)
OJ上的一些水题(可用来练手和增加自信) (poj3299,poj2159,poj2739,poj1083,poj2262,poj1503,poj3006,poj2255,poj3094)初期: 一. ...
- 【转】ACM训练计划
[转] POJ推荐50题以及ACM训练方案 -- : 转载自 wade_wang 最终编辑 000lzl POJ 推荐50题 第一类 动态规划(至少6题, 和 必做) 和 (可贪心) (稍难) 第二类 ...
随机推荐
- el-date-picker 日期格式化 yyyy-MM-dd
<el-date-picker format="yyyy-MM-dd" v-model="dateValue" type="date" ...
- node启动服务
npm install http-server -g http-server ipconfig查看当前ip 手机可访问第一个网址.
- linux===给新手的 10 个有用 Linux 命令行技巧(转)
本文转自:http://www.codeceo.com/article/10-linux-useful-command.html?ref=myread 仅用作学习交流使用.如有侵权,立删 我记得我第一 ...
- mac系统中实现vitualBox中访问内网端口
第一步,增加外网网段 打开vitualbox后,按管理菜单,点击->主机网络管理器,如图1所示.点击创建,创建下个网络主机. 图1 然后,关掉虚拟机,虚拟机的设置中,找到网络选项卡,然后点击网络 ...
- API(全局配置,全局API)
全局配置 Vue.config是一个对象,包含Vue的全局配置 silent 类型:boolean 默认值:false 用法 Vue.config.silent=true 取消Vue所有的日志与警告 ...
- Dev的js智能提示
VS中"工具"->"选项"->"文本编辑器"->"JavaScript"->"Inte ...
- FineReport——插入行策略
1.空值是默认的选项,即每次插入新行时,格子都是空白的. 2.原值即单元格中原有内容是什么,就复制到新增的格子中,一般适用于单元格是使用公式定义的, 在插入单元格时,公式会保留下来. 3.默认值即通过 ...
- MYSQL中INET_ATON()函数
例如我们现在要在一个表中查出 ip 在 192.168.1.3 到 192.168.1.20 之间的 ip 地址,我们首先想到的就是通过字符串的比较来获取查找结果,但是如果我们通过这种方式来查找,结果 ...
- memcache和redis的对比
1.memcache a.Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站 ...
- layui文件单文件和多文件的上传、预览以及删除和修改
活不多说,直接上代码 单文件上传 1.HTML <blockquote class="layui-elem-quote layui-quote-nm" style=" ...