Dijkstra、Dij + heap、Floyd、SPFA、 SPFA + SLF Template
Dijkstra in Adjacency matrix :
int Dijkstra(int src,int tec, int n){
bool done[];
int d[];
memset(done,,sizeof(done));
map[][src] = ;//巧妙之处,加入超级源点0
for(int i = ;i <= n;i++)
d[i] = (i == src ? : );
for(int i = ;i <= n;i++){//最多执行n+1次操作
int minx,minn = ;
for(int j = ;j <= n;j++)//先找到d[]最小的点
if(!done[j] && d[j] < minn){
minn = d[j];
minx = j;
}
done[minx] = ;//将该点加入集合
if(minx == ter) return d[minx];
for(int j = ;j <= n;j++){//再更新所有的d[]
if(!done[j] && d[minx] + map[minx][j] < d[j]){
d[j] = d[minx] + map[minx][j];
}
}
}
return -;//如果没有找到到终点的路径,返回-1
}
Dijkstra in Adjacency list :
int dijkstra(int src,int ter){//src源点,ter终点
vist[src] = ;
dist[src] = ;
for(int i = head[src];i != -;i = edge[i].pre ){
dist[edge[i].cur] = edge[i].w; //dist[x]保存从源点到节点x当前最短距离
}
for(int i = ;i < n;i ++){
int cur = ,Min = inf;
for(int j = ;j <= n;j ++){
if(!vist[j] && dist[j] < Min){
Min = dist[j];
cur = j;
}
}
vist[cur] = ;
if(cur == ter) return dist[cur];
//当ter被标记为访问过时,说明当前dist[ter]已经为src到ter的最短距离
for(int j = head[cur];j != -;j = edge[j].pre ){
int to = edge[j].cur;
if(!vist[to]){
dist[to] = min(dist[to],dist[cur] + edge[j].w);
}
}
}
return dist[ter];
}
Dijkstra + heap :
int dijkstra(int src,int ter){
vist[src] = ;
dist[src] = ;
priority_queue<node>q;
/*
struct node{
int v,dist;//顶点和距离
node(int vv,int ddist){v=vv,dist=ddist;}
bool operator<(const node &A)const{return dist > A.dist;}//最小优先
};
*/
q.push(node(src,));
int cur = src;
for(int i = ;i < n;i ++){
for(int j = head[cur];j != -;j = edge[j].pre ){
int to = edge[j].cur;
if(!vist[to] && dist[to]>dist[cur]+edge[j].w){
dist[to] = dist[cur] + edge[j].w;
q.push(node(to,dist[to]));
}
}
while(!q.empty()&&vist[q.top().v]){
q.pop();
}
cur = q.top().v;q.pop();
vist[cur] = ;
if(cur == ter)break;
}
return dist[ter];
}
Floyd :
简单描述一下Floyd:首先我们需要一个邻接矩阵
(所谓邻接矩阵是一个 n*n 的矩阵, 第i行第j列的值为value 表示i点到j点的距离为value
.若i到j点不可达时我们可以使value=inf)
注意传递闭包的概念, 得到一个传递闭包至多将任意两点松弛n次。
第一层for是用k点去松弛, 第二层和第三层for是对于任意两点i、j。
#define inf 1000000000
// init***************
for(int i = ; i <= n; i++)
for(int j = ; j <= n; j++)
dp[i][j] = inf;
//****************
//--------------Floyd:
for(int k = ; k <= n; k++)
for(int i = ; i <= n; i++)if(i!=k && dp[i][k] != inf)
for(int j = ; j <= n; j++)if(j!=i && j!=k)
dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j]);
//--------------
for(int i = ; i <= n; i++) dp[i][i] = ;
SPFA:
1、注意对于最短路中存在负权判定:对于spfa算法
当某个点入队列(入队列的意义就是该点被松弛了(更新))次数>n次,
就说明该点在负权上(可以简单证明一个点至多被更新n次(n为图中的顶点数))。
2、优先队列:出队的元素不是在队尾的元素,
而是队列中最小的元素(我们有时可以在队列中存储结构体元素,只需重载运算符即可)。
struct node{
int x, y;
bool operator<(const node&a) const
{ if(a.x==x) return a.y<y; return a.x<x; } //根据x,y值比较node结构体的大小
};
3、状态压缩:当某些状态只有true or false,时我们可以用一个整数来表示这个状态。
示例:
有3块不同的蛋糕编号1、2、3, 被老鼠啃过, 那么蛋糕只有2种状态, 我们用0表示没有被啃过, 1表示被啃过。
显然我们可以得到所有状态:000、001、010、011、100、101、110、111.
而上述二进制数对应的整数为 [0, 2^3) . (如二进制011 = 整数3表示 第2、3块蛋糕被啃过,第一块蛋糕没有被啃过)
我们可以用 for(int i = 0; i < (1<<3); i++) 来遍历所有的状态。
把多个事物的状态利用二进制含义压缩为一个整数称为状态压缩。
4、利用优先队列优化最短路时, 我们可以先出队距离起点最近的点, 则若出队的为终点显然我们已经得到了一条最短路了。
SPFA in Adjacency list :
The LONGEST PATH:
struct node{
int u,v,val,next;
} Edge[MAXN];
void addEdge(int u,int v,int val){
Edge[cnt].u=u;
Edge[cnt].v=v;
Edge[cnt].val=val;
Edge[cnt].next=head[u];
head[u]=cnt++;
}
int spfa(){
//for(int i=src;i<=ter;i++) dis[i]=-INF;
queue<int>q;
q.push(src);
vis[src]=;
dis[src]=;
while(!q.empty()){
int u=q.front();
q.pop();
vis[u]=;
for(int i=head[u]; i!=-; i=Edge[i].next){
int v=Edge[i].v;
if(dis[v]<dis[u]+Edge[i].val){
dis[v]=dis[u]+Edge[i].val;
if(!vis[v]){
vis[v]=;
q.push(v);
}
}
}
}
return dis[ter];
}
SPFA + SLF in Adjacency list :
The LONGEST PATH:
int spfa(int src,int ter){
//for(int i=src;i<=ter;i++) dis[i]=-INF;
deque<int>q;
q.push_back(src);
vis[src] = ;//标记当前顶点是否在队列中
dis[src] = ;
while(!q.empty()){
int u = q.front();
q.pop_front();
vis[u] = ;
for(int i = head[u];i != -;i = Edge[i].next){
int v = Edge[i].v;
if(dis[v] < dis[u] + Edge[i].val){//松弛
dis[v] = dis[u] + Edge[i].val;
if(!vis[v]){
vis[v] = ;
if(!q.empty()&&dis[v]<dis[q.front()])//SLF优化
q.push_front(v);
else q.push_back(v);
}
}
}
}
return dis[ter];
}
Dijkstra、Dij + heap、Floyd、SPFA、 SPFA + SLF Template的更多相关文章
- Dijkstra、Bellman_Ford、SPFA、Floyd算法复杂度比较
参考 有空再更新下用c++, 下面用的Java Dijkstra:适用于权值为非负的图的单源最短路径,用斐波那契堆的复杂度O(E+VlgV) BellmanFord:适用于权值有负值的图的单源最短路径 ...
- Linux内存管理(text、rodata、data、bss、stack&heap)
一.各内存区段的介绍 系统内的程序分为程序段和数据段,具体又可细分为一下几个部分: (1)text段-代码段 text段存放程序代码,运行前就已经确定(编译时确定),通常为只读,可以直接在ROM或Fl ...
- 【Java面试题】解释内存中的栈(stack)、堆(heap)和静态存储区的用法
Java面试题:解释内存中的栈(stack).堆(heap)和静态存储区的用法 堆区: 专门用来保存对象的实例(new 创建的对象和数组),实际上也只是保存对象实例的属性值,属性的类型和对象本身的类型 ...
- 内存管理概述、内存分配与释放、地址映射机制(mm_struct, vm_area_struct)、malloc/free 的实现
http://blog.csdn.net/pi9nc/article/details/23334659 注:本分类下文章大多整理自<深入分析linux内核源代码>一书,另有参考其他一些资料 ...
- mysql系列十一、mysql优化笔记:表设计、sql优化、配置优化
可以从这些方面进行优化: 数据库(表)设计合理 SQL语句优化 数据库配置优化 系统层.硬件层优化 数据库设计 关系数据库三范式 1NF:字段不可分; 2NF:有主键,非主键字段依赖主键; 3NF:非 ...
- 2.1、Hibernate多表操作--一对多、多对一、多对多。
一.什么是一对一.一对多.多对一及多对多关系(以简单的学生和老师的关系为例来说): 1.一对一:学生具有学号和姓名(假定没有同名的学生)这两个属性,那么我知道了学生的学号也就能找到对应的学生姓名,如果 ...
- Atitit 面向对象编程(OOP)、面向组件编程(COP)、面向方面编程(AOP)和面向服务编程(SOP)的区别和联系
Atitit 面向对象编程(OOP).面向组件编程(COP).面向方面编程(AOP)和面向服务编程(SOP)的区别和联系 1. 面向组件编程(COP) 所以,组件比起对象来的进步就在于通用的规范的引入 ...
- Windows网络驱动、NDIS驱动(微端口驱动、中间层驱动、协议驱动)、TDI驱动(网络传输层过滤)、WFP(Windows Filtering Platform)
catalog . 引言 . Windows 2000网络结构和OSI模型 . NDIS驱动 . NDIS微端口驱动编程实例 . NDIS中间层驱动编程实例 . NDIS协议层驱动编程实例 . TDI ...
- Unit06 - 抽象类、接口和内部类(下) 、 面向对象汇总
Unit06 - 抽象类.接口和内部类(下) . 面向对象汇总 1.多态: 1)意义: 1.1)同一类型的引用指向不同的对象时,有不同的实现 行为的多态:cut().run(). ...
随机推荐
- <转> Python的优雅技巧
枚举 不要这么做: 全选复制放进笔记 i = 0 for item in iterable: print i, item i += 1 而是这样: 全选复制放进笔记 for i, item in en ...
- React使用笔记(3)-React Event Listener
Date: 2015-11-28 12:18 Category: Web Tags: JavaScript Author: 刘理想 [toc] 1. 构造基本结构 首先,我们先创建一个按钮,一个输入框 ...
- 批量 GBK 转 UTF8 java
package encoding; import java.io.File; import java.io.IOException; import java.util.Collection; impo ...
- 帝国cms7.0 内容页控制简介字数!
帝国cms7.0 内容页有简介部分,使用以下代码可以有效控制字数限制! 下载类简介:<?=esub($navinfor[softsay],160)?> 文章类简介:<?=esub($ ...
- 【Leetcode】Triangle
给定一个由数字组成的三角形,从顶至底找出路径最小和. Given a triangle, find the minimum path sum from top to bottom. Each step ...
- 74HC595的中文资料
74HC595--具有三态输出锁存功能的8位串行输入.串行/并行输出移位寄存器 本文翻译自NXP的74HC595的datasheet 74HC595和74HCT595是带有存储寄存器和三态输出的8位串 ...
- rman备份优化思路
本章不讲rman备份原理.仅仅提供一些思路 1.oracle11g 选择压缩算法为中级: 2.添加rman备份的通道. 以上两种做法.添加CPU的利用率,降低IO 3.指定rate參数 这个rate和 ...
- hdu 4782 Beautiful Soupz
模拟.其实这题就是题目比较长而已...读完题目就差不多了.tag直接读就可以了,题目说了不用修改.然后整个题目就是让求text部分,严格按空格分开.注意每行前面空格个数. #include<al ...
- Python:爬取乌云厂商列表,使用BeautifulSoup解析
在SSS论坛看到有人写的Python爬取乌云厂商,想练一下手,就照着重新写了一遍 原帖:http://bbs.sssie.com/thread-965-1-1.html #coding:utf- im ...
- Nginx 之一:编译安装nginx 1.8.1 及配置
一:基介绍 官网地址www.nginx.org,nginx是由1994年毕业于俄罗斯国立莫斯科鲍曼科技大学的同学为俄罗斯rambler.ru公司开发的,开发工作最早从2002年开始,第一次公开发布时间 ...