hdu1874(最短路:一道题学习Floyd,Dijkstra,Bellman-Ford,SPFA)
2015-07-30 13:09
399 查看
Floyd,Dijkstra,Bellman-Ford,SPFA的比较
/article/7665028.html
Floyd(动态规划)
1,从任意一条单边路径开始。所有两点之间的距离是边的权,
如果两点之间没有边相连,则权为无穷大。
2,对于每一对顶点 u 和 v,看看是否存在一个顶点 w 使得从 u 到 w 再到 v 比已知的路径更短,
如果是更新它。
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中包含所有顶点
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),则此图存在负权环
SPFA---------bfs方法
/article/7665028.html
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; }
相关文章推荐
- git分支创建失败 dev创建feature失败
- 63. Unique Paths II
- WSHPSRS-匹克选择列表生成器-SRS(R12.2.3)
- C++访问MySQL数据
- Codeforces Round #286 (Div. 2) C. Mr. Kitayuta, the Treasure Hunter dp+范围压缩
- hdoj2955
- Android内存管理之道
- Windows API函数 WaitForMultiObjects 的使用注意事项
- 读书笔记16:组合模式
- 读书笔记15:备忘录模式
- SpringMVC 流程(5)-- 视图解析器
- 读书笔记14:适配器模式
- 【转】 依赖注入框架Autofac的简单使用
- linux mint sublime3的c编译环境配置
- MySQL函数
- java 方法对 二、八、十、十六进制之间的转换
- 读书笔记13:状态模式
- Treap树(并查集 + 树堆)POJ —— 2985 The k-th Largest Group
- 如何成为一名黑客
- python main