最短路(模板)【CodeChef CLIQUED,洛谷P3371】
自TG滚粗后咕咕咕了这么久,最近重新开始学OI,也会慢慢开始更博了。。。。
最短路算法经典的就是SPFA(Bellman-Ford),Dijkstra,Floyd;
本期先讲两个经典的单源最短路算法:
首先是我最喜(hao)欢(xie)的SPFA(可惜经常被卡)
SPFA:
Warning:SPFA在OI竞赛中慎用,极易容易被卡!!!
基本流程:
从起点开始,每次将扫到的点入队,每个点遍历所有与其相连的点,并更新最短路,如果该点未入队,则将其入队;
均摊复杂度为$ O(KE) $(K=2),但因为SPFA在网格图中入队次数过多,导致卡成原始的Bellman-Ford($ o(VE) $),所以竞赛中不常用到(但还是要学会的);
丑陋的代码(洛谷P3371):
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,x,y,z,tot,f[],q[],h,t,s,first[],nxt[],last[],en[],len[];
//f为记录最短路径的数组,q为队列;
//first,nxt,last,en,len为平平无奇的邻接表;
bool b[];
//判断是否在队列中
void add(int x,int y,int z)
{
++tot;
if(first[x]==) first[x]=tot; else nxt[last[x]]=tot;
en[tot]=y;
len[tot]=z;
last[x]=tot;
}
void SPFA(int x)
{
int k=first[x];
do
{
if((long long)len[k]+f[x]<f[en[k]])
{
f[en[k]]=len[k]+f[x];
if(not b[en[k]])
{
++t;
q[t]=en[k];
b[en[k]]=true;
}
}
k=nxt[k];
}
while(k!=);
}
int main()
{
scanf("%d%d%d",&n,&m,&s);
for(int i=;i<=m;++i)
{
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
}
for(int i=;i<=n;++i)
f[i]=;
f[s]=;
h=;
t=;
SPFA(s);
while(h<=t)
{
SPFA(q[h]);
b[q[h]]=false;
++h;
}
for(int i=;i<=n;++i)
printf("%d ",f[i]);
return ;
}
Dijkstra:
最常用的最短路算法(蒟蒻的我最近才学会太菜了);
基本流程:
定义两个点的集合,S为已求出最短路的点集,T为未求出最短路的点集;
每次在T集合中找到一个Dis值最小的点,将其放入S集合中,并用它更新其他点的最短路;
由此,朴素的Dijkstra在每次选择操作中暴力枚举每个点复杂度为$ O(V) $,更新时的复杂度也为$ O(V) $,及时间复杂度为$ O(V^2) $;
聪(AK)明(IOI)的读者可能已经发现了,选择Dis值最小的点时,暴力枚举过于浪费,为了避免超时,我们可以用堆(或者线段树)优化为$ o(Vlog(E)) $;
每次选择时,直接访问堆的根节点,将其弹出,并把更新的节点压入堆中;(每次压入堆中不必要判是否已入堆,只需要开个bool数组记录该点是否已有最短路即可)
(甚至可以用斐波那契堆优化为$ o(E+Vlog(V)) $)
附上丑陋的代码(CodeChef CLIQUED):
#include<cstdio>
#include<queue>
#include<iostream>
using namespace std;
const int MAXN=;
const long long INF=1e15+;
struct node
{
int pos;
long long dis;
bool operator <(const node &x)const
{
return x.dis<dis;
}
};
priority_queue<node> q;
int tot,first[MAXN],nxt[MAXN],last[MAXN],to[MAXN],len[MAXN];
//平平无奇的邻接表
int T,n,k,x,m,s;
long long dis[MAXN];
//dis为到每个点的最短路径
bool vis[MAXN];
//vis记录每个点是否已有最短路的值
void dijistra()
{
dis[s]=;
q.push((node){s,});
while(!q.empty())
{
node t=q.top();
int po=t.pos;
long long di=t.dis;
q.pop();
//取堆的根节点
if(vis[po])
continue;
//如果已有最短路,说明该点已更新过,无需更新
vis[po]=;
for(int i=first[po];i;i=nxt[i])
if(di+len[i]<dis[to[i]])
{
dis[to[i]]=di+len[i];
q.push((node){to[i],di+len[i]});
}
//常规松弛(更新最短路径)
}
}
void add(int x,int y,int z)
{
tot++;
if(first[x]==)
first[x]=tot;
else
nxt[last[x]]=tot;
last[x]=tot;
to[tot]=y;
len[tot]=z;
}
int main()
{
scanf("%d",&T);
for(int ii=;ii<=T;++ii)
{
scanf("%d%d%d%d%d",&n,&k,&x,&m,&s);
n++;
for(int i=;i<=n;++i)
first[i]=;
for(int i=;i<=m;++i)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
add(y,x,z);
}
for(int i=;i<=k;++i)
{
add(i,n,x);
add(n,i,);
}
for(int i=;i<=n;++i)
dis[i]=INF;
for(int i=;i<=n;++i)
vis[i]=;
dijistra();
for(int i=;i<n;++i)
printf("%lld ",dis[i]);
printf("\n");
}
return ;
}
最短路(模板)【CodeChef CLIQUED,洛谷P3371】的更多相关文章
- 第K短路模板【POJ2449 / 洛谷2483 / BZOJ1975 / HDU6181】
1.到底如何求k短路的? 我们考虑,要求k短路,要先求出最短路/次短路/第三短路……/第(k-1)短路,然后访问到第k短路. 接下来的方法就是如此操作的. 2.f(x)的意义? 我们得到的f(x)更小 ...
- 最小生成树 & 洛谷P3366【模板】最小生成树 & 洛谷P2820 局域网
嗯... 理解生成树的概念: 在一幅图中将所有n个点连接起来的n-1条边所形成的树. 最小生成树: 边权之和最小的生成树. 最小瓶颈生成树: 对于带权图,最大权值最小的生成树. 如何操作? 1.Pri ...
- AC自动机模板3【洛谷3796】
AC自动机的第三个模板 其实,个人觉得,目前我写的这三个不同的模板完全是可以合并在一起求解的. 只是,在这两个无关联的OJ上,同一个AC自动机都可以完成的问题被拆成了三道题而已. 因此,代码只需要略加 ...
- 洛谷 P3371 【模板】单源最短路径
P3371 [模板]单源最短路径 题目描述 如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度. 输入输出格式 输入格式: 第一行包含三个整数N.M.S,分别表示点的个数.有向边的个数.出 ...
- 洛谷 P3371 【模板】单源最短路径(弱化版) && dijkstra模板
嗯... 题目链接:https://www.luogu.org/problem/P3371 没什么好说的,这是一个最短路的模板,这里用的dijkstra做的... 注意: 1.dijkstra和邻接表 ...
- 洛谷P3371 【模板】单源最短路径
P3371 [模板]单源最短路径 282通过 1.1K提交 题目提供者HansBug 标签 难度普及/提高- 提交 讨论 题解 最新讨论 不萌也是新,老司机求带 求看,spfa跑模板40分 为什么 ...
- 洛谷 P3371 【模板】单源最短路径(弱化版) 题解
P3371 [模板]单源最短路径(弱化版) 题目背景 本题测试数据为随机数据,在考试中可能会出现构造数据让SPFA不通过,如有需要请移步 P4779. 题目描述 如题,给出一个有向图,请输出从某一点出 ...
- 单源最短路径spfa模板(pascal)洛谷P3371
题目描述 如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度. 输入输出格式 输入格式: 第一行包含三个整数N.M.S,分别表示点的个数.有向边的个数.出发点的编号. 接下来M行每行包含三 ...
- 最短路径Dijkstra算法模板题---洛谷P3371 【模板】单源最短路径(弱化版)
题目背景 本题测试数据为随机数据,在考试中可能会出现构造数据让SPFA不通过,如有需要请移步 P4779. 题目描述 如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度. 输入格式 第一行 ...
随机推荐
- idea中怎么去查看maven项目的依赖包是否有冲突
1:快捷键:
- python的浅复制,深复制
1.a = b是将b的id复制给b,然后a与b指向同一个对象 import numpy as np a = np.arange(5) print(a) b = a print(id(a)) print ...
- [Git] 026 config 命令的补充
少废话,上例子 1. 让命令更醒目 $ git config --global color.ui true 2. 偷懒 $ git config --global alias.st status 使用 ...
- Maven 项目中的groupId和artifactId
maven进行项目管理,如果我们要将项目加入到maven到本地仓库中,则需要对项目进行唯一性标示,而groupId和artifactId就起到这样对作用. groupId为项目组织对唯一标识符,可以理 ...
- FHJ学长的心愿 QDUOJ 数论
FHJ学长的心愿 原题链接,点我进去 题意 给你一个数N,让你求在\[C^{0}_{n} \ C^{1}_{n}\ C^{2}_{n}\ \dots \ C^{n}_{n}\]中有几个组合数是奇数. ...
- docker下部署kafka集群(多个broker+多个zookeeper)
网上关于kafka集群的搭建,基本是单个broker和单个zookeeper,测试研究的意义不大.于是折腾了下,终于把正宗的Kafka集群搭建出来了,在折腾中遇到了很多坑,后续有时间再专门整理份搭建问 ...
- vue-sticky组件详解
sticky简介 sticky的本意是粘的,粘性的,使用其进行的布局被称为粘性布局. sticky是position属性新推出的值,属于CSS3的新特性,常用与实现吸附效果. 设置了sticky布局的 ...
- c# 杀死占用某个文件的进程
原文:c# 杀死占用某个文件的进程 需要使用微软提供的工具Handle.exe string fileName = @"H:\abc.dll";//要检查被那个进程占用的文件 Pr ...
- UITextField 文本框 只能输入数字 且保留2位小数 实现
http://blog.sina.com.cn/s/blog_aa7579f601015xvx.html #pragma mark - #pragma mark UITextField - (BOOL ...
- Zookeeper入门概要
ZooKeeper是一个开源的分布式协调服务,由雅虎创建,是Google Chubby的开源实现.ZooKeeper的设计目标是将那些复杂且容易出错的分布式一致性服务封装起来,构成一个高效可靠的原语集 ...