最短路 Bellman-Ford 边上权值任意的单源最短路
2012-08-16 19:03
435 查看
小B算法:
怎样都好,就是不能图中包含负权值回路。。!
假如图中有n个点,那么我们需要将图遍历(因为有n-1条边)n-1次(邻接表)或n-2(邻接矩阵,因为有初始化),每次遍历的时候,拿出一个点(u),再与其他个点比较(v),如果起始点到u距离大于 起始点到v的距离加上u到v的距离,那么就更新。直到所有的点拿完,再去遍历吧。。
判断存在负权值回路方法:
遍历完n-1边以后,我们在更新一次所有点,如果还能更改,那么一定存在负权值回路。
*做了一些题,发现这个算法用于判断回路比较多,比如负权值回路与正权值回路。也可以结合flody算法来用,flody算法判断两点关系,是否可到达。然后在来用bellman-ford判断回路求解。如果在点i j存在回路,i到n可达,那么balabala....之类的用法。
code:
邻接矩阵 时间复杂度 O(n3)
邻接表 时间复杂度 O(nm)
怎样都好,就是不能图中包含负权值回路。。!
假如图中有n个点,那么我们需要将图遍历(因为有n-1条边)n-1次(邻接表)或n-2(邻接矩阵,因为有初始化),每次遍历的时候,拿出一个点(u),再与其他个点比较(v),如果起始点到u距离大于 起始点到v的距离加上u到v的距离,那么就更新。直到所有的点拿完,再去遍历吧。。
判断存在负权值回路方法:
遍历完n-1边以后,我们在更新一次所有点,如果还能更改,那么一定存在负权值回路。
*做了一些题,发现这个算法用于判断回路比较多,比如负权值回路与正权值回路。也可以结合flody算法来用,flody算法判断两点关系,是否可到达。然后在来用bellman-ford判断回路求解。如果在点i j存在回路,i到n可达,那么balabala....之类的用法。
code:
邻接矩阵 时间复杂度 O(n3)
#include<stdio.h> #include<string.h> #define MX 100000 int n,m,map[100][100],path[100],dist[100]; void bellman(int v0) { for(int i=0;i<n;i++) { dist[i]=map[v0][i]; if(map[v0][i]<MX) path[i]=v0; else path[i]=-1; } dist[v0]=0; for(int i=0;i<n-2;i++) //遍历n-2遍 { for(int j=0;j<n;j++) //拿出一个点 { if(j!=v0) { for(int k=0;k<n;k++) //在拿出另外一个点,开始更新 { if(map[k][j]<MX&&dist[k]+map[k][j]<dist[j]) { path[j]=k; dist[j]=dist[k]+map[k][j]; } } } } } } int main() { while(scanf("%d%d",&n,&m)!=EOF) { for(int i=0;i<n;i++) for(int j=0;j<n;j++) map[i][j]=MX; for(int i=0;i<m;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); map[a][b]=c; } bellman(0); int pa[100]; for(int i=0;i<n;i++) { printf("%d\n",dist[i]); int now=i,k=1; pa[0]=i; while(path[now]!=-1) { pa[k]=path[now]; now=path[now]; k++; } for(int j=k-1;j>0;j--) printf("%d ->",pa[j]); printf("%d\n",pa[0]); } } return 0; }邻接表判断有负权值回路
for(int i=0;i<n;i++) { for(int j=0;j<n;j++) if(map[j][i]<MX&&dist[j]+map[j][i]<dist[i]) return false; //有负环回路 } return true; //没有负环回路
邻接表 时间复杂度 O(nm)
#include<stdio.h> #include<string.h> #define MX 1000000 int n,m,dist[100],path[100]; struct point { int u,v,w; }eg[100]; void bellman(int v0) { for(int i=0;i<n;i++) { path[i]=-1; dist[i]=MX; } dist[v0]=0; for(int i=0;i<n-1;i++) { for(int j=0;j<m;j++) { if(dist[eg[j].u]<MX&&dist[eg[j].u]+eg[j].w<dist[eg[j].v]) { dist[eg[j].v]=dist[eg[j].u]+eg[j].w; path[eg[j].v]=eg[j].u; } } } } int main() { while(scanf("%d%d",&n,&m)!=EOF) { for(int i=0;i<m;i++) scanf("%d%d%d",&eg[i].u,&eg[i].v,&eg[i].w); bellman(0); for(int i=1;i<n;i++) { int now=i,k=1; int pa[100];pa[0]=i; printf("%d\n",dist[i]); while(path[now]!=-1) { pa[k]=path[now]; now=path[now]; k++; } for(int j=k-1;j>0;j--) printf("%d->",pa[j]); printf("%d\n",pa[0]); } } return 0; }邻接表判断负环回路
for(int i=0;i<m;i++) { if(dist[eg[i].u]+eg[i].w<dist[eg[i].v]) return false; //存在 } return true; //不存在负环回路
相关文章推荐
- 边上权值为任意值的单源最短路径问题——Bellman--Ford算法
- 最短路模板(Dijkstra & Dijkstra算法+堆优化 & bellman_ford & 单源最短路SPFA)
- 最短路(2)--bellman-ford和SPFA
- 图论 最短路 Bellman_Ford 专题
- Wormholes( POJ 3259)(Bellman-Ford+SPFA)(判断是否有负权环)(最短路模板)
- hdu 2544 【总结】 Dijkstra,Bellman-Ford ,SPFA 最短路求法及对应优化
- poj2240 Bellman-ford最短路求最大回路
- 最短路 bellman-ford
- ACM模板 Bellman_Ford,单源最短路,图论
- nullnull图论最短路之bellman-ford
- UVA 10986 - Sending email(最短路 优先队列的优化+Bellman-Ford)
- Bellman_Ford ----->最短路
- 基础最短路(模板 bellman_ford)
- HDU2544_最短路(Dijkstra)(Bellman-Ford)(SPFA+邻接表/邻接矩阵)
- HDU 2544 最短路(四种写法:Floyd、Dijkstra、Bellman-Ford、SPFA)
- hdu 2544 【总结】 Dijkstra,Bellman-Ford ,SPFA 最短路求法及对应优化
- 图论总结 Dijkstra Tarjan 最小生成树 二分图 最短路 强连通分量 双连通分量 Bellman-Ford SPFA 二分图染色 Kruskal Prim 网络流 二分图匹配 Dinic
- Wormholes(最短路_bellman_ford)
- Currency Exchange POJ - 1860 单源最短路 Bellman_Ford
- poj 1860 2378 3259带负边最短路 ** bellman ford 模板