最短路(模板)【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. 题目描述 如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度. 输入格式 第一行 ...
随机推荐
- 【bzoj4710】[Jsoi2011]分特产
JYY 带队参加了若干场ACM/ICPC 比赛,带回了许多土特产,要分给实验室的同学们. JYY 想知道,把这些特产分给N 个同学,一共有多少种不同的分法?当然,JYY 不希望任何一个同学因为没有拿到 ...
- python每日一练:0012题
第 0012 题: 敏感词文本文件 filtered_words.txt,里面的内容 和 0011题一样,当用户输入敏感词语,则用 星号 * 替换,例如当用户输入「北京是个好城市」,则变成「**是个好 ...
- 应用安全 - 编程语言漏洞 - PHP语言漏洞汇总
CVE-2019-11043 Date: 类型: 远程代码执行 前置条件: Nginx + fastcgi + php-fpm 配置文件信息如下: location ~ [^/]\.php(/|$) ...
- Monkey学习笔记(一)
(一)adb相关命令语句: 1. 查看连接设备信息:adb devices 2.安装app到手机上:adb install [-r] [apk文件存在地址].apk 3.将文件放入设备/模拟器:ad ...
- 6.float类型 和 char 类型
float32 float64 package main import "fmt" func main() { var xxx float32 var xxxx float64 ...
- 通过编写串口助手工具学习MFC过程——(二)通过“打开串口”按钮了解基本操作
通过编写串口助手工具学习MFC过程 因为以前也做过几次MFC的编程,每次都是项目完成时,MFC基本操作清楚了,但是过好长时间不再接触MFC的项目,再次做MFC的项目时,又要从头开始熟悉.这次通过做一个 ...
- 编写的Java第一个程序
没什么好介绍的,嘻嘻 package head; public class ee { public static void main(String[] args) { System.out.print ...
- HDU 1594 find the max
数序问题. 题意是说 一个数列 a1,a2,--ai,--an; x=i , y = ai:找两个点斜率绝对值.!最大. 第一次没找绝对值,--认真读题. .. x 每次加1 . 仅仅须要找 相邻的 ...
- Could not locate executable null\bin\winutils.exe in the Hadoop binaries解决方式
1. 问题: 2. 问题解决: 仔细查看报错是缺少winutils.exe程序. Hadoop都是运行在Linux系统下的,在windows下eclipse中运行mapreduce程序,要首先安装 ...
- ASP.net解析JSON
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...