题意:求最短路径
主要想是学习下SPFA,所以用这个算法来写的
学习链接:http://www.cnblogs.com/devtang/archive/2011/08/25/spfa.html
http://blog.sina.com.cn/s/blog_a46817ff01015g9h.html
SPFA(Shortest Path Faster Algorithm)算法
1、是求单源最短路径的一种算法;2判断图中有无负圈
SPFA(Shortest Path Faster Algorithm)是Bellman-Ford算法的一种队列实现,减少了不必要的冗余计算。
它可以在O(kE)的时间复杂度内求出源点到其他所有点的最短路径,可以处理负圈(如果存在负边不可以用dirkstra算法做原因如下:Dijkstra不断维护最小,每次走使当前权值最小的能边,那么一旦有负的权值每次从这里通过总的权值和就会越来越小,那么这条边会一直是最小边,
Dijkstra算法会使你陷入死循环,不断在这条负权值的边两端的点来回
,但是如果存在负圈,那么最短路不存在,可用SPFA判断有无负圈存在)。若一个点入队次数超过n,则有负权环。
算法大致流程是用一个队列来进行维护
注意点:在实际的应用中SPFA的算法时间效率不是很稳定,为了避免最坏情况的出现,通常使用效率更加稳定的Dijkstra算法。
算法实现:
Dist[i]记录源点到i点的距离
1、 建立一个队列,将源点入队列,初始化源点的dist为0,其他点为oo
2、 每次取队首元素,对其相邻点松弛,松弛成功的入队列
主要想是学习下SPFA,所以用这个算法来写的
学习链接:http://www.cnblogs.com/devtang/archive/2011/08/25/spfa.html
http://blog.sina.com.cn/s/blog_a46817ff01015g9h.html
SPFA(Shortest Path Faster Algorithm)算法
1、是求单源最短路径的一种算法;2判断图中有无负圈
SPFA(Shortest Path Faster Algorithm)是Bellman-Ford算法的一种队列实现,减少了不必要的冗余计算。
它可以在O(kE)的时间复杂度内求出源点到其他所有点的最短路径,可以处理负圈(如果存在负边不可以用dirkstra算法做原因如下:Dijkstra不断维护最小,每次走使当前权值最小的能边,那么一旦有负的权值每次从这里通过总的权值和就会越来越小,那么这条边会一直是最小边,
Dijkstra算法会使你陷入死循环,不断在这条负权值的边两端的点来回
,但是如果存在负圈,那么最短路不存在,可用SPFA判断有无负圈存在)。若一个点入队次数超过n,则有负权环。
算法大致流程是用一个队列来进行维护
注意点:在实际的应用中SPFA的算法时间效率不是很稳定,为了避免最坏情况的出现,通常使用效率更加稳定的Dijkstra算法。
算法实现:
Dist[i]记录源点到i点的距离
1、 建立一个队列,将源点入队列,初始化源点的dist为0,其他点为oo
2、 每次取队首元素,对其相邻点松弛,松弛成功的入队列
3、 队列为空时算法结束
模板题
代码如下:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<time.h>
#include<math.h>
#define N 205
#define inf 0x7ffffff
#define eps 1e-9
#define pi acos(-1.0)
#define P system("pause")
using namespace std;
int n,m;
int mp[N][N],dist[N],vis[N];
queue<int> q;
void SPFA(int s)
{
memset(vis,0,sizeof(vis));
while(!q.empty()) q.pop();
int i;
for(i = 0; i < n; i++)//注意这里和dijkstra算法不一样
dist[i] = inf;
dist[s] = 0;
q.push(s);
vis[s] = 1;
while(!q.empty())
{
int temp = q.front();
//cout<<temp<<endl;
q.pop();
for(i = 0; i < n; i++)
if(dist[i] > mp[temp][i]+dist[temp])
{
dist[i] = dist[temp] + mp[temp][i];
if(!vis[i])
{
//cout<<i<<endl;
q.push(i);
vis[i] =1;
}
}
vis[temp] = 0;
}
}
int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
while(scanf("%d%d",&n,&m) != EOF)
{
int i,j;
for(i = 0; i < n; i++)
for(j = 0; j < n; j++)
mp[i][j] = mp[j][i] = inf;
for(i = 0 ; i < m; i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
if(mp[x][y] > z)
mp[x][y] = mp[y][x] = z;
}
int start ,end;
scanf("%d%d",&start,&end);
SPFA(start);
if(dist[end] == inf) printf("%d\n",-1);
else printf("%d\n", dist[end]);
}
return 0;
}