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 ...
随机推荐
- 数往知来 asp.net 聊天室问题解决方案<十六>
1:在服务端创建了一个负责监听的sokcet //三个:采用TCP协议. ListenSocket = new Socket(AddressFamily.InterN ...
- 大数据时代的数据存储,非关系型数据库MongoDB
在过去的很长一段时间中,关系型数据库(Relational Database Management System)一直是最主流的数据库解决方案,他运用真实世界中事物与关系来解释数据库中抽象的数据架构. ...
- Thrift框架介绍
1.前言 Thrift是一个跨语言的服务部署框架,最初由Facebook于2007年开发,2008年进入Apache开源项目.Thrift通过一个中间语言(IDL, 接口定义语言)来定义RPC的接口和 ...
- s3c2440串口裸板驱动(使用fifo)
使用fifo的好处有: 1:串口的数据发送的数据量较大时,使用fifo可以大大降低MCU的开销.(有点类似串入并出的cput处理模型,本质上还是串行收发) 2:在某些特殊场合,例如制定较复杂的协议时, ...
- 【原创译文】基于Docker和Rancher的超融合容器云架构
基于Docker和Rancher的超融合容器云架构 ---来自Rancher和Redapt 超融合架构在现代数据中心是一项巨大的变革.Nutanix公司发明了超融合架构理论,自从我听说他们的“iPho ...
- 设置UINavigationController相同标题
设置UINavigationController相同标题,让UINavigationController内的每一个ViewController的标题都一样,可以使用以下设置. UINavigation ...
- java.io.IOException: Messenger was closed
程序运行一段时间后抛出异常java.io.IOException: Messenger was closed,不知道是啥原因? ———————————————————————————————————— ...
- <系统函数实现>memcmp
这是我实现的memcmp函数: #include <stdio.h> #include <string.h> /* *int memcmp (const void *s1,co ...
- iis 支持html执行php输出
iis 支持html执行php输出 2012-07-25 10:50:23| 分类: PHP|举报|字号 订阅 在HTML中有个简单的的PHP随机数需要输出,例如: <td backg ...
- C#中的结构体与类的区别
经常听到有朋友在讨论C#中的结构与类有什么区别.正好这几日闲来无事,自己总结一下,希望大家指点. 1. 首先是语法定义上的区别啦,这个就不用多说了.定义类使用关键字class 定义结构使用关键字str ...