自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】的更多相关文章

  1. 第K短路模板【POJ2449 / 洛谷2483 / BZOJ1975 / HDU6181】

    1.到底如何求k短路的? 我们考虑,要求k短路,要先求出最短路/次短路/第三短路……/第(k-1)短路,然后访问到第k短路. 接下来的方法就是如此操作的. 2.f(x)的意义? 我们得到的f(x)更小 ...

  2. 最小生成树 & 洛谷P3366【模板】最小生成树 & 洛谷P2820 局域网

    嗯... 理解生成树的概念: 在一幅图中将所有n个点连接起来的n-1条边所形成的树. 最小生成树: 边权之和最小的生成树. 最小瓶颈生成树: 对于带权图,最大权值最小的生成树. 如何操作? 1.Pri ...

  3. AC自动机模板3【洛谷3796】

    AC自动机的第三个模板 其实,个人觉得,目前我写的这三个不同的模板完全是可以合并在一起求解的. 只是,在这两个无关联的OJ上,同一个AC自动机都可以完成的问题被拆成了三道题而已. 因此,代码只需要略加 ...

  4. 洛谷 P3371 【模板】单源最短路径

    P3371 [模板]单源最短路径 题目描述 如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度. 输入输出格式 输入格式: 第一行包含三个整数N.M.S,分别表示点的个数.有向边的个数.出 ...

  5. 洛谷 P3371 【模板】单源最短路径(弱化版) && dijkstra模板

    嗯... 题目链接:https://www.luogu.org/problem/P3371 没什么好说的,这是一个最短路的模板,这里用的dijkstra做的... 注意: 1.dijkstra和邻接表 ...

  6. 洛谷P3371 【模板】单源最短路径

    P3371 [模板]单源最短路径 282通过 1.1K提交 题目提供者HansBug 标签 难度普及/提高- 提交  讨论  题解 最新讨论 不萌也是新,老司机求带 求看,spfa跑模板40分 为什么 ...

  7. 洛谷 P3371 【模板】单源最短路径(弱化版) 题解

    P3371 [模板]单源最短路径(弱化版) 题目背景 本题测试数据为随机数据,在考试中可能会出现构造数据让SPFA不通过,如有需要请移步 P4779. 题目描述 如题,给出一个有向图,请输出从某一点出 ...

  8. 单源最短路径spfa模板(pascal)洛谷P3371

    题目描述 如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度. 输入输出格式 输入格式: 第一行包含三个整数N.M.S,分别表示点的个数.有向边的个数.出发点的编号. 接下来M行每行包含三 ...

  9. 最短路径Dijkstra算法模板题---洛谷P3371 【模板】单源最短路径(弱化版)

    题目背景 本题测试数据为随机数据,在考试中可能会出现构造数据让SPFA不通过,如有需要请移步 P4779. 题目描述 如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度. 输入格式 第一行 ...

随机推荐

  1. Dos - 学习总结(1)

    1.控制台复制 1>鼠标右键,标记. 2>选定复制内容后,鼠标右键,完成复制. 2.

  2. 安装Linux系统CentOS6.5

    个人机器搭建分布式环境时避免要使用虚拟机来满足分布式环境所需的机器,当然伪分布式除外. 简单记录下虚拟机环境的创建过程,Mac上常用的虚拟机VMware Fusion. 虚拟机资源库中新建虚拟机: 选 ...

  3. Windows上Tomcat安装以及解决乱码问题

    Windows上Tomcat安装以及解决乱码问题 下载tomcat8 1.进入tomcat官网 官方网站 2.选择windows的版本 解压 确定自己配置好了jdk jdk的相关配置 配置好tomca ...

  4. 搜索专题: HDU1026Ignatius and the Princess I

    Ignatius and the Princess I Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (J ...

  5. 缓存字节流-写coppy方法

    package ba; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io. ...

  6. 《CSS权威指南》双鱼书详解——第二章选择器

    一.基本规则 CSS的核心特性就是能向文档中的一组元素类型应用某些规则. 二.规则结构 选择器+声明块. h1{ color:red;background:yellow;} ,声明块由一个或多个声明组 ...

  7. vue脚手架通过UI界面创建项目

    vue脚手架提供了图形界面操作项目,比之前通过命令操作的形式还要简单,以下是使用的步骤: 1.全局安装@vue/cli脚手架工具 npm i @vue/cli -g {使用淘宝镜像:npm insta ...

  8. Mysql批量更新的一个坑-&allowMultiQueries=true允许批量更新

    前言        实际上,我们经常会遇到这样的需求,那就是利用Mybatis批量更新或者批量插入,但是,实际上即使Mybatis完美支持你的sql,你也得看看你说操作的数据库是否支持,而阿福,最近就 ...

  9. AFNetworking2.0源码解析<四>

    结构 AFURLResponseSerialization负责解析网络返回数据,检查数据是否合法,把NSData数据转成相应的对象,内置的转换器有json,xml,plist,image,用户可以很方 ...

  10. eclipse项目添加到本地仓库

    右键项目→Team→Add to Index 提交后,项目变化如下: *表示已经提交到暂存区,可以进行提交操作 右键项目→Team→Commit 可以填写提交信息: 点击信息下面的commit按钮 项 ...