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(). ...
随机推荐
- java 类排序
参考文档:Java排序: Comparator vs Comparable 入门 java类经常面临排序问题,据我所知:java提供comparable和comparator两种比较方式: 1. co ...
- CentOS5.4下安装codeblocks 12.11
centos6.3下安装codeblock简单多了,这些开源的软件也都在不断进步.原来装过codeblocks10.05,忘了,这次安装又花了我半天时间,最后总算搞定. 先是安装了wxGTK-2.8. ...
- Myeclipse利用maven构建sping web项目
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQQAAADvCAIAAACbnj2oAAAfq0lEQVR4nO2d+1MUV9rH+294U9mqpG ...
- 模拟美萍加密狗--Rockey2虚拟狗(一)
目录(?)[+] 最近受朋友之托做了一个美萍智能电源控制的插件.美萍茶楼从2010版开始支持智能电源控制设备,就是开单.结账时自动开关相应房间的电器,不过官方的设备是有线的.朋友的店已经开了一段时 ...
- 静态方法中为什么不能使用this
- POCO C++ lib开发环境构建
Welcome Thank you for downloading the POCO C++ Libraries and welcome to the growing community of POC ...
- 代码收藏 JS实现页内查找定位功能
前部分为IE下搜索方法 用TextRange来实现 后部分为firefox.chrome下搜索方法 var nextIndex = 0; var searchValue = ''; var input ...
- HDOJ 1429 胜利大逃亡(续) (bfs+状态压缩)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1429 思路分析:题目要求找出最短的逃亡路径,但是与一般的问题不同,该问题增加了门与钥匙约束条件: 考虑 ...
- nodejs--express开发博客系统(三)
上一节已经实现了登录.注册.发表文章和文章读取的功能,今天咱加上评论.文章页面和作者页面. 评论只能在进入文章页面后才能进行,所以咱们先写文章页面. 在上一节的代码中,我已经给文章标题添加了超链接了, ...
- Windows最常用的几个网络CMD命令总结
Windows最常用的几个网络CMD命令总结 http://www.cnblogs.com/sbaicl/archive/2013/03/05/2944001.html 一.ping 主要是测试本机T ...