Floyd,Dijkstra,Bellman-Ford,SPFA的比较
http://blog.csdn.net/xiazdong/article/details/8193680
Floyd(动态规划)
1,从任意一条单边路径开始。所有两点之间的距离是边的权,
如果两点之间没有边相连,则权为无穷大。
2,对于每一对顶点 u 和 v,看看是否存在一个顶点 w 使得从 u 到 w 再到 v 比已知的路径更短,
如果是更新它。
#include <cstdio>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#define MAXN 1005
#define MAX 205
#define INF 0xfffffff
using namespace std;
//struct Path{int u,v,w;}path[MAXN];
int mp[MAX][MAX];
int s,e,n,m;
int u,v,w;
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
//Floyd算法
for(int i=0;i<n;i++) for(int j=0;j<n;j++) if(i!=j)mp[i][j]=INF;
for(int i=0;i<m;i++){
scanf("%d%d%d",&u,&v,&w);
if(mp[u][v]>w) mp[u][v]=mp[v][u]=w;
}
scanf("%d%d",&s,&e);
for(int k=0;k<n;k++)
for(int i=0;i<n;i++)
for(int j=0;j<n;j++){
int t=mp[i][k]+mp[k][j];
if(mp[i][j]>t) mp[i][j]=t;
}
if(mp[s][e]<INF) printf("%d\n",mp[s][e]);
else printf("-1\n");
}//while
return 0;
}
Dijkstra(贪心)
1,初始时令 起点s加入集合A,其余顶点组成集合B,
B中顶点对应的距离值若存在<s,bi>,dis(bi)>为其权值,若不存在dis(bi)为∞
2.,从B中选取一个与A中顶点有关联边且权值最小的顶点t,加入到S中
3.,对其余A中顶点的距离值进行修改:若加进t作中间顶点,从as到ai的距离值缩短,
则修改此距离值重复上述步骤2、3,直到A中包含所有顶点
#include <cstdio>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <queue>
#define MAXN 1005
#define MAX 205
#define INF 0xfffffff
using namespace std;
//struct Path{int u,v,w;}path[MAXN];
int mp[MAX][MAX];
int s,e,n,m;
int u,v,w;
int dis[MAX],vis[MAX];
void Dijkstra(){
int i,j,k,mi;
memset(vis,0,sizeof(vis));
for(i=0;i<n;i++) dis[i]=mp[s][i];
dis[s]=0;
for(i=0;i<n;i++){
mi=INF;
for(j=0;j<n;j++){
if(!vis[j]&&dis[j]<mi){
mi=dis[j];
k=j;
}//if
}//for_j
if(mi==INF) break;
vis[k]=1;
for(j=0;j<n;j++)
if(!vis[j]&&dis[j]>dis[k]+mp[k][j])
dis[j]=dis[k]+mp[k][j];
}
if(dis[e]<INF) printf("%d\n",dis[e]);
else printf("-1\n");
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
for(int i=0;i<n;i++) for(int j=0;j<n;j++) mp[i][j]=INF;
for(int i=0;i<m;i++){
scanf("%d%d%d",&u,&v,&w);
if(mp[u][v]>w) mp[u][v]=mp[v][u]=w;
}
scanf("%d%d",&s,&e);
Dijkstra();
}//while
return 0;
}
Bellman-Ford
1,初始化:将除源点外的所有顶点的最短距离值 d[i]置为∞, d[s]=0;
2,迭代求解:对每条边 ,dist[Vi] + (Vi,Vj)和dist[Vj],并将小的赋给dist[Vj]
(重复以上操作n − 1次)
3,检验负权回路(本题略)再重复操作一次,如dist[Vj] > dist[Vi] + (Vi,Vj),则此图存在负权环
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string.h>
#include <string>
#include <vector>
#include <queue>
#define MEM(a,x) memset(a,x,sizeof a)
#define eps 1e-8
#define MOD 10009
#define MAXN 205
#define MAXM 2005
#define INF 99999999
#define ll __int64
#define bug cout<<"here"<<endl
#define fread freopen("ceshi.txt","r",stdin)
#define fwrite freopen("out.txt","w",stdout)
using namespace std;
int n,m,s,e;
struct Path{
int u,v,w;
}p[MAXM];
int dis[MAXN];
void Bellman_Ford(){
int i,j;
for(i=0;i<n;i++) dis[i] = INF;
dis[s]=0;
for(i=0;i<n;i++)
for(j=0;j<2*m;j++)
dis[p[j].u]=min(dis[p[j].u],dis[p[j].v]+p[j].w);
if(dis[e]<INF) printf("%d\n",dis[e]);
else printf("-1\n");
}
int main(){
int u,v,w;
int i,j;
while(scanf("%d%d",&n,&m)!=EOF){
s=1;e=n;
int num=0;
//for(i=0;i<=n;i++) for(j=0;j<=n;j++) mp[i][j]=INF;
for(i=0;i<m;i++){
scanf("%d%d%d",&u,&v,&w);
p[num].u=u;
p[num].v=v;
p[num++].w=w;
p[num].u=v;
p[num].v=u;
p[num++].w=w;
}
scanf("%d%d",&s,&e);
Bellman_Ford();
}
return 0;
}
SPFA———bfs方法
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <queue>
#include <set>
using namespace std;
#define INF 999999999
int mp[210][210],flag[210],d[210];
int m,n,s,e;
void SPFA(){
int i,x;
queue<int>q;
memset(flag,0,sizeof(flag));
for(i=0;i<n;i++) d[i]=INF;
d[s]=0;
q.push(s);
while(!q.empty()){
x=q.front();
q.pop();
flag[x]=0;
for(i=0;i<n;i++){
if(d[i]>d[x]+mp[x][i]){
d[i]=d[x]+mp[x][i];
if(!flag[i]){q.push(i);flag[i]=1;}
}//if
}//for
}//while
printf("%d\n",d[e]<INF?d[e]:-1);
}
int main(){
int i,j,a,b,c;
while(scanf("%d%d",&n,&m)!=EOF){
for(i=0;i<n;i++)for(j=0;j<n;j++)mp[i][j]=INF;
for(i=0;i<m;i++){
scanf("%d%d%d",&a,&b,&c);
if(mp[a][b]>c) mp[a][b]=mp[b][a]=c;
}
scanf("%d%d",&s,&e);
SPFA();
}
return 0;
}