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(). ...
随机推荐
- 转:在控制台中调试AngularJS应用
在控制台中调试AngularJS应用 在创建AngularJS应用时,一个很棘手的问题是如何在Chrome,Firefox,以及IE的JavaScript控制台中访问深藏在应用中的数据和服务.本文将会 ...
- 转: object 和embed 标签播放flash
一.介绍: 我们要在网页中正常显示flash内容,那么页面中必须要有指定flash路径的标 签.也就是OBJECT和 EMBED标签.OBJECT标签是用于windows平台的IE浏览器的,而EMBE ...
- 玩转无线 — GNURADIO 简单运用
大家好, 我是Insight-labs的旺财,这里放出个旺财在Bsides Toronto 2013 会上RF-Ninjia Hacking议题中的一个案例,随着物联网越来越火热,而物联网又离不开无线 ...
- perl5 第九章 关联数组/哈希表
第九章 关联数组/哈希表 by flamephoenix 一.数组变量的限制二.定义三.访问关联数组的元素四.增加元素五.创建关联数组六.从数组变量复制到关联数组七.元素的增删八.列出数组的索引和值九 ...
- Cocos2d_x的特点及环境配置
Cocos2d_x的特点: 什么是"x"?Cocos2d_x方式:有时候我们写的cpp文件扩展,CXX."X"标致着该项目是由c++,并提供c++中的API编写 ...
- 为什么每个程序员都应该用Mac OS X?
1.Mac OS X 是基于 Unix 的.这一点太重要了,尤其是对开发人员,至少对于我来说很重要,这意味着Unix 下一堆好用的工具都可以随手捡到.如果你是个 windows 开发人员,我想你会在 ...
- HDU 4859(Bestcoder #1 1003)海岸线(网络流之最小割)
题目地址:HDU4859 做了做杭电多校,知识点会的太少了.还是将重点放在刷专题补知识点上吧,明年的多校才是重点. 这题题目求的最长周长.能够试想一下,这里的海岸线一定是在"."和 ...
- js设置奇偶行数样式
$(document).ready(function () { odd = { "background": "none" }; //奇数样式 even = { ...
- springdata+redis配置详解
springdata设计初衷是位简化数据类型和数据的持久化存储,它并不局限是关系型数据库还是nosql数据库,都提供了简化的数据库连接,让数据获取变得更加的简单.所有这些的实现有统一的api提供. 本 ...
- JavaSE学习总结第14天_API常用对象4
14.01 如何校验一个QQ号码案例 import java.util.Scanner; /* * 校验qq号码. * 1:要求必须是5-15位数字 * 2:0不能开头 * * 分析: * A:键 ...