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年开始,第一次公开发布时间 ... 
