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(). ...
随机推荐
- bmfont制作数字
http://blog.csdn.net/z104207/article/details/20136401
- Qt在Linux环境下应用程序字体模糊的解决方法(先改成使用默认字体,然后使用qtconfig配置)
这两天一直在用Qt实现一个跨平台的软件.软件之前在Windows上编写的,后来放到里Ubuntu 10.10下编译.程序运行时遇到一个很棘手的问题,界面文本非常模糊.后来在网上查阅了好几天的资料,经历 ...
- sed 文件查找,替换
sed 命令查找与替换: (1)删除第2,3行:sed '2,3d' test.txt > new.txt (2)替换: 替换所有:sed 's/abc/ABC/' test.txt > ...
- cython教程
.写测试代码: zhouhh@zhouhh-home:~$ vi test.pyx [python] view plaincopy def sayhello(char* str): if str == ...
- HDU 2178 猜数字
题解:设猜到的最大的数是h,在1到h间,你最多只要猜log2(h)+1(取整)次,所以易知==>h=2^m-1.即猜m次,能猜到的最大的数为2^m-1. #include <cstdio& ...
- hdoj 1824 Let's go home(2-SAT)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1824 思路分析:该问题为2-SAT问题:需要注意逻辑推理的等价性: (1)题目第一个条件:每一个队或者 ...
- hive 0.10 0.11新增特性综述
我们的hive版本升迁经历了0.7.1 -> 0.8.1 -> 0.9.0,并且线上shark所依赖的hive版本也停留在0.9.0上,在这些版本上有我们自己的bug fix patch和 ...
- ZYB's Game(博弈)
ZYB's Game Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total ...
- C++的一些编程规范(基于google)
1.所有头文件都应该使用#define 防止头文件被多重包含,命名格式可以参考<PROJECT>_<PATH>_<FILE>_H 2.使用前置声明尽量减少.h文件中 ...
- 浅谈CSS布局
在No.4中谈及了下盒子模型,引出布局模型 1.布局模型有三类: 1)流动模型 flow(默认) 2)浮动模型 float 3)层模型 layer 2.文档流 :指的是文本沿着从左到右的方向展开 ...