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 ...
随机推荐
- 在logopond中看到的优秀设计随想
本随笔仅仅只是自己对于设计作品的想法,不喜勿喷~ 昨日看到关于大神配色的文章,决定在logopond网站中看看优秀的作品,以为自己的配色找找灵感,学习学习,对自己有很强的震撼力的有: 以女性高跟性的抽 ...
- xshell 上传 下载文件
借助XShell,使用linux命令sz可以很方便的将服务器上的文件下载到本地,使用rz命令则是把本地文件上传到服务器. sz用法: 下载一个文件 sz filename 下载多个文件 sz file ...
- [翻译]HTML中不知名的语义标签
原文:http://docs.webplatform.org/wiki/tutorials/Lesser_-_known_semantic_elements HTML5中比较常用的语义元素有heade ...
- Make the “Check out” function available in the office document opened with Document ID link
I found a solution to make the “Check out” function available in the office document opened with Doc ...
- 【131】如何讲好PPT
1 列提纲2 写稿子3 背稿子4 演练5遍,用自己的话说出来,最好和稿子一样,但不强求一样,关键要理解5 不一定要做,但是做好了会有很大提高,讲的时候也会很NB:有时间可以再演练几遍,录出来看看哪里需 ...
- 用UltraISO制作的u盘ubuntu11.04,启动失败解决方案
错误提示:SYSLINUX 3.84 2009-12-18 EBIOS Copyright c 1994-2009 H.Peter Anvin et al 折腾的很久,尝试用Pauly的bootice ...
- UVaLive 7512 November 11th (思维漏洞)
题意:给定n*m个座椅,然后有b个是坏的,要做人,并且两个人不能相邻,问你最多坐多少人,最少坐多少人. 析:这个题其实并不难,只要当时一时没想清楚,结果就一直WA,就是最少的情况时,其实一个人可以占三 ...
- shell常见语法
#!/bin/bashecho "**********argument**********"echo script name: $0echo first argument $1ec ...
- [LeetCode] Consecutive Numbers 连续的数字 --数据库知识(mysql)
1. 题目名称 Consecutive Numbers 2 .题目地址 https://leetcode.com/problems/consecutive-numbers/ 3. 题目内容 写一个 ...
- 【Netbeans】表格的使用
参数两个:一个二维数组赋予数据,一个一位数组赋予属性名