ACM-最短路(SPFA,Dijkstra,Floyd)之最短路——hdu2544
***************************************转载请注明出处:http://blog.csdn.net/lttree***************************************
最短路
Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 28761 Accepted Submission(s): 12444
可是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候。却是非常累的!
所以如今他们想要寻找最短的从商店到赛场的路线,你能够帮助他们吗?
输入保证至少存在1条商店到赛场的路线。
2 1
1 2 3
3 3
1 2 5
2 3 5
3 1 2
0 0
3
2
题目: pid=2544">http://acm.hdu.edu.cn/showproblem.php? pid=2544
求最短路,我是看《挑战程序设计竞赛》里的书学的。
里面介绍了三种方法: Bellman-Ford、Dijkstra and Floyd
三者差别也都非常明显:
Bellman-Ford:
求单源最短路,能够推断有无负权回路(若有。则不存在最短路)。 时效性较好。时间复杂度O(VE)。
Bellman-Ford算法是求解单源最短路径问题的一种算法。
单源点的最短路径问题是指: 给定一个加权有向图G和源点s。对于图G中的随意一点v。求从s到v的最短路径。
与Dijkstra算法不同的是。在Bellman-Ford算法中,边的权值能够为负数。
设想从我们能够从图中找到一个环路(即从v出发。经过若干个点之后又回到v)且这个环路中全部边的权值之和为负。那么通过这个环路,环路中随意两点的最短路径就能够无穷小下去。
假设不处理这个负环路。程序就会永远执行下去。 而Bellman-Ford算法具有分辨这样的负环路的能力。
Dijkstra:
求单源、无负权的最短路。时效性较好,时间复杂度为O(V*V+E)。 源点可达的话。O(V*lgV+E*lgV)=>O(E*lgV)。 当是稀疏图的情况时。此时E=V*V/lgV,所以算法的时间复杂度可为O(V^2) 。若是斐波那契堆作优先队列的话,算法时间复杂度。则为O(V*lgV + E)。
Floyd:
求多源、无负权边的最短路。用矩阵记录图。
时效性较差,时间复杂度O(V^3)。 Floyd-Warshall算法(Floyd-Warshall algorithm)是解决随意两点间的最短路径的一种算法,能够正确处理有向图或负权的最短路径问题。
Floyd-Warshall算法的时间复杂度为O(N^3),空间复杂度为O(N^2)。
Floyd-Warshall的原理是动态规划: 设Di,j,k为从i到j的仅仅以(1..k)集合中的节点为中间节点的最短路径的长度。 若最短路径经过点k,则Di,j,k = Di,k,k-1 + Dk,j,k-1; 若最短路径不经过点k,则Di,j,k = Di,j,k-1。 因此,Di,j,k = min(Di,k,k-1 + Dk,j,k-1 , Di,j,k-1)。
在实际算法中,为了节约空间,能够直接在原来空间上进行迭代,这样空间可降至二维。
Floyd-Warshall算法的描写叙述例如以下: for k ← 1 to n do for i ← 1 to n do for j ← 1 to n do if (Di,k + Dk,j < Di,j) then Di,j ← Di,k + Dk,j; 当中Di,j表示由点i到点j的代价,当Di,j为 ∞ 表示两点之间没有不论什么连接。
后来,我看Bellman-Ford的队列优化,SPFA(Shortest Path Faster Algorithm )。
SPFA:
是Bellman-Ford的队列优化,时效性相对好。时间复杂度O(kE)。(k<<V)。
与Bellman-ford算法类似,SPFA算法採用一系列的松弛操作以得到从某一个节点出发到达图中其他全部节点的最短路径。所不同的是,SPFA算法通过维护一个队列。使得一个节点的当前最短路径被更新之后没有必要立马去更新其他的节点。从而大大降低了反复的操作次数。
SPFA算法能够用于存在负数边权的图,这与dijkstra算法是不同的。
与Dijkstra算法与Bellman-ford算法都不同。SPFA的算法时间效率是不稳定的,即它对于不同的图所须要的时间有非常大的区别。
在最好情形下。每个节点都仅仅入队一次,则算法实际上变为广度优先遍历,其时间复杂度仅为O(E)。还有一方面。存在这种样例,使得每个节点都被入队(V-1)次,此时算法退化为Bellman-ford算法,其时间复杂度为O(VE)。
SPFA算法在负边权图上能够全然代替Bellman-ford算法,另外在稀疏图中也表现良好。可是在非负边权图中,为了避免最坏情况的出现,通常使用效率更加稳定的Dijkstra算法,以及它的使用堆优化的版本号。通常的SPFA算法在一类网格图中的表现不尽如人意。
然后,这道题我用了SPFA。Dijkstra和Floyd来做(Bellman-Ford 太慢。就不做了)
这道题。当时我怎么做。做不出来,后来发现是 MAX 设定为 0x7fffffff 问题。设置成别的大数就没事。
贡献了N个WA啊!!
。
郁闷ING。。。
SPFA:
/****************************************
*****************************************
* Author:Tree *
*From :http://blog.csdn.net/lttree *
* Title : 最短路 *
*Source: hdu 2544 *
* Hint : SPFA *
*****************************************
****************************************/ #include <stdio.h>
#include <queue>
using namespace std; #define RANGE 101
#define MAX 0x3f3f3f3f
int cost[RANGE][RANGE];
int d[RANGE];
bool used[RANGE];
int n,m; void spfa( int s )
{
int i,now;
// 初始化
for( i=1;i<=n;++i )
{
d[i]=MAX;
used[i]=false;
} d[s]=0;
queue <int> q;
q.push(s);
used[s] = true; while(!q.empty())
{
now = q.front();
q.pop();
used[now] = false;
for(i = 1; i <= n; i++)
{
if(d[i] > d[now] + cost[now][i])
{
d[i] = d[now] + cost[now][i];
if(used[i] == 0)
{
q.push(i);
used[i] = true;
}
}
}
}
} int main()
{
int i,j,A,B,C;
while( scanf("%d%d",&n,&m) )
{
if( !n && !m ) break;
// 初始化
for( i=1;i<=n;++i )
for( j=1;j<=i;++j )
if( i==j ) cost[i][j]=0;
else cost[i][j]=cost[j][i]=MAX; for( i=0;i<m;++i )
{
scanf("%d%d%d",&A,&B,&C);
cost[A][B]=cost[B][A]=C;
} spfa(1);
printf("%d\n",d[n]);
}
return 0;
}
Dijkstra:
/****************************************
*****************************************
* Author:Tree *
*From :http://blog.csdn.net/lttree *
* Title : 最短路 *
*Source: hdu 2544 *
* Hint : Dijkstra *
*****************************************
****************************************/ #include <stdio.h>
#define MAX 0x3f3f3f3f
#define RANGE 101 int cost[RANGE][RANGE];
int d[RANGE];
bool used[RANGE]; int n,m;
int Min( int a,int b )
{
return a<b? a:b;
} void Dijkstra( int s )
{
int i,v,u;
for( i=1;i<=n;++i )
{
used[i]=false;
d[i]=cost[1][i];
}
d[s]=0; while( true )
{
v=-1;
for( u=1;u<=n;++u )
if( !used[u] && ( v==-1 || d[u]<d[v]) )
v=u;
if( v==-1 ) break;
used[v]=true; for( u=1;u<=n;++u )
d[u]=Min( d[u],d[v]+cost[v][u] );
}
} int main()
{
int A,B,C,i,j; while( scanf("%d%d",&n,&m) )
{
if( !n && !m ) break; // 初始化
for( i=1;i<=n;++i )
for( j=1;j<=i;++j )
if( i==j ) cost[i][j]=0;
else cost[i][j]=cost[j][i]=MAX; for( i=0;i<m;++i )
{
scanf("%d%d%d",&A,&B,&C);
cost[A][B]=cost[B][A]=C;
} Dijkstra(1);
printf("%d\n",d[n]);
}
return 0;
}
Floyd:
/****************************************
*****************************************
* Author:Tree *
*From :http://blog.csdn.net/lttree *
* Title : 最短路 *
*Source: hdu 2544 *
* Hint : Floyd *
*****************************************
****************************************/ #include <stdio.h>
#define MAX 0x3f3f3f3f
#define RANGE 105 int d[RANGE][RANGE];
int n; int Min( int a,int b )
{
return a<b?a:b;
}
void warshall_floyd( void )
{
int i,j,k;
for( k=1;k<=n;++k )
for( i=1;i<=n;++i )
for( j=1;j<=n;++j )
d[i][j]=Min( d[i][j],d[i][k]+d[k][j] );
} int main()
{
int m,A,B,C,i,j; while( scanf("%d%d",&n,&m) )
{
if( !n && !m ) break; // 初始化
for( i=1;i<=n;++i )
for( j=1;j<=i;++j )
{
if( i==j ) d[i][j]=0;
else d[i][j]=d[j][i]=MAX;
} // 输入
for( i=0;i<m;++i )
{
scanf("%d%d%d",&A,&B,&C);
d[A][B]=d[B][A]=C;
} // floyd算法求最短路
warshall_floyd();
printf("%d\n",d[1][n]);
}
return 0;
}
ACM-最短路(SPFA,Dijkstra,Floyd)之最短路——hdu2544的更多相关文章
- 关于SPFA Bellman-Ford Dijkstra Floyd BFS最短路的共同点与区别
关于模板什么的还有算法的具体介绍 戳我 这里我们只做所有最短路的具体分析. 那么同是求解最短路,这些算法到底有什么区别和联系: 对于BFS来说,他没有松弛操作,他的理论思想是从每一点做树形便利,那么时 ...
- hdoj2544 最短路(Dijkstra || Floyd || SPFA)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=2544 思路 最短路算法模板题,求解使用的Dijkstra算法.Floyd算法.SPFA算法可以当做求解 ...
- dijkstra,SPFA,Floyd求最短路
Dijkstra: 裸的算法,O(n^2),使用邻接矩阵: 算法思想: 定义两个集合,一开始集合1只有一个源点,集合2有剩下的点. STEP1:在集合2中找一个到源点距离最近的顶点k:min{d[k] ...
- HDU 1874 畅通工程续 SPFA || dijkstra||floyd
http://acm.hdu.edu.cn/showproblem.php?pid=1874 题目大意: 给你一些点,让你求S到T的最短路径. 我只是来练习一下SPFA的 dijkstra+邻接矩阵 ...
- 最短路-SPFA算法&Floyd算法
SPFA算法 算法复杂度 SPFA 算法是 Bellman-Ford算法 的队列优化算法的别称,通常用于求含负权边的单源最短路径,以及判负权环. SPFA一般情况复杂度是O(m)最坏情况下复杂度和朴素 ...
- hdu3665-Seaside(SPFA,dijkstra,floyd)
Seaside Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Su ...
- HDU 1874 畅通工程续(最短路/spfa Dijkstra 邻接矩阵+邻接表)
题目链接: 传送门 畅通工程续 Time Limit: 1000MS Memory Limit: 65536K Description 某省自从实行了很多年的畅通工程计划后,终于修建了很多路. ...
- HDU 1874 SPFA/Dijkstra/Floyd
这题作为模板题,解法好多... 最近周围的人都在搞图论阿,感觉我好辣鸡,只会跟风学习. 暂时只有SPFA和Dijkstra的 SPFA (邻接表版.也可以写成临接矩阵存图,但题目可能给出平行边的,所以 ...
- 最短路模板|堆优化Dijkstra,SPFA,floyd
Ⅰ:Dijkstra单源点最短路 1.1Dijkstra const int MAX_N = 10000; const int MAX_M = 100000; const int inf = 0x3f ...
随机推荐
- mybatis源码学习: 动态代理的应用(慢慢改)
动态代理概述 在学spring的时候知道使用动态代理实现aop,入门的列子:需要计算所有方法的调用时间.可以每个方法开始和结束都获取当前时间咋办呢.类似这样: long current=system. ...
- 数往知来C#之接口 值类型与引用类型 静态非静态 异常处理 GC垃圾回收 值类型引用类型内存分配<四>
C# 基础接口篇 一.多态复习 使用个new来实现,使用virtual与override -->new隐藏父类方法 根据当前类型,电泳对应的方法(成员) -->override ...
- extjs 学习笔记(二)
EXTJS实用开发指南 1. 要使用ExtJS 框架的页面中一般包括下面几句: <link rel="stylesheet" type="text/css" ...
- 代理(Proxy)模式简介
Proxy 模式简介 代理模式的两个应用: 打开文档时加载大图片 例如:如果有个对象是一张很大的图片,而这张图片需要花费很长时间才能显示出来,那么当这个图片包含在文档中的后面时,使用编辑器或浏览器打开 ...
- OC使用inline替代宏
CG_INLINE voidGCDDelay(int64_t delayInSeconds,dispatch_block_t block){ dispatch_time_t popTime = dis ...
- cc.Sprite
Classcc.Sprite Defined in: CCSprite.js Extends cc.NodeRGBA Class Summary Constructor Attributes Cons ...
- DataGrid Column Group (合并表头)
<thead> <tr> <th colspan=">swjg</th> <th colspan=">swbm</ ...
- 【下载】支持中文的 jspSmartUpload jar 包
http://www.blogjava.net/hijackwust/archive/2007/08/22/138598.html —————————————————————————————————— ...
- ACM 中常用的算法有哪些? 2014-08-21 21:15 40人阅读 评论(0) 收藏
ACM 中常用的算法有哪些?作者: 张俊Michael 网络上流传的答案有很多,估计提问者也曾经去网上搜过.所以根据自己微薄的经验提点看法. 我ACM初期是训练编码能力,以水题为主(就是没有任何算法, ...
- Dynamic Method Resolution
[Dynamic Method Resolution] @dynamic directive 用于声明属性的方法dynamic loading,which tells the compiler tha ...