watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzQ4NzA1MQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" width="900" height="500" alt="">

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzQ4NzA1MQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" width="900" height="400" alt="">

</pre><pre name="code" class="cpp">

#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
#include<vector> using namespace std; const int INF = 0x3f3f3f3f;//无穷大
const int maxn = 20;//顶点个数的最大值
int n;//顶点个数
int edge[maxn][maxn];//邻接矩阵
//Dijkstra算法用到的3个数组
int s[maxn];//记录顶点是否在集合中
int dist[maxn];//记录路径的权值
int path[maxn];//记录路径 void Dijkstra( int v0 )//求v0到其它点的最短路径
{
int i, j, k;//循环变量
for(i=0; i<n; i++)
{
dist[i] = edge[v0][i];
s[i] = 0;
if( i!=v0 && dist[i]<INF )
path[i] = v0;
else
path[i] = -1;
}
s[v0] = 1; dist[v0] = 0;//顶点v0增加顶点集合s
for(i=0; i<n-1; i++)//从顶点v0确定n-1条最短路径
{
int min = INF, u = v0;
//选择当前集合T中具有最短路径的顶点u
for(j=0; j<n; j++)
{
if( !s[j] && dist[j]<min )
{
u = j;
min = dist[j];
}
}
s[u] = 1;//将顶点u增加集合s。表示它的最短路径已求得
//改动T集合中顶点的dist和path数组元素
for(k=0; k<n; k++)
{
if( !s[k] && edge[u][k]<INF && dist[u]+edge[u][k]<dist[k] )
{
dist[k] = dist[u] + edge[u][k];
path[k] = u;
}
}
}
} int main()
{
int i, j;//循环变量
int u, v, w;//边的起点和终点以及权值
scanf("%d", &n);//读入顶点个数n
while(1)
{
scanf("%d%d%d", &u, &v, &w);
if( u==-1 && v==-1 && w==-1 )
break;
edge[u][v] = w;//构建邻接矩阵
}
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
{
if( i==j )
edge[i][j] = 0;
else if( edge[i][j] == 0 )
edge[i][j] = INF;
}
}
Dijkstra(0);//求顶点0到其它顶点的最短路径
int shortest[maxn];//输出最短路径上的各个顶点时存放各个顶点的序号
for(i=1; i<n; i++)
{
printf("%d\t", dist[i]);//输出顶点0到顶点i的最短路径长度
//下面代码用于输出顶点0带顶点i的最短路径
memset( shortest, 0, sizeof(shortest) );
int k = 0;//k表示shorttest数组中最后一个元素的下标
shortest[k] = i;
while( path[ shortest[k] ]!=0 )
{
k++;
shortest[k] = path[shortest[k-1]];
//printf("%d ", k);
}
k++; shortest[k] = 0;
//printf("%d", k);
for(j=k; j>0; j--)
printf("%d--", shortest[j]);
printf("%d\n", shortest[0]);
} return 0;
}

Bellman:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
#include<vector> using namespace std; const int INF = 0x3f3f3f3f;
const int maxn = 8;
int edge[maxn][maxn];
int dist[maxn];
int path[maxn];
int n; void Bellman(int v0)
{
int i, j, k, u;
for(i=0; i<n; i++)
{
dist[i] = edge[v0][i];
if( i!=v0 && dist[i] < INF )
path[i] = v0;
else
path[i] = -1;
}
for(k=2; k<n; k++)
{
for(u=0; u<n; u++)
{
if( u!=v0 )
{
for( j=0; j<n; j++ )
{
if( edge[j][u] < INF && dist[j] + edge[j][u] < dist[u] )
{
dist[u] = dist[j] + edge[j][u];
path[u] = j;
}
}
}
}
}
} int main()
{
int i, j;
int u, v, w;
scanf("%d", &n);
while( 1 )
{
scanf("%d%d%d", &u, &v, &w);
if( u==-1 && v==-1 && w==-1 )
break;
edge[u][v] = w;
}
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
{
if( i==j )
edge[i][j] = 0;
else if( edge[i][j]==0 )
edge[i][j] = INF;
}
}
Bellman(0);
int shortest[maxn];
for(i=1; i<n; i++)
{
printf("%d\t", dist[i]);
memset( shortest, 0, sizeof(shortest) );
int k = 0;
shortest[k] = i;
while( path[shortest[k]]!=0 )
{
k++;
shortest[k] = path[shortest[k-1]];
}
k++;
shortest[k] = 0;
for(j=k; j>0; j--)
printf("%d--", shortest[j]);
printf("%d\n", shortest[0]);
} return 0;
}

SPFA:

#include <cstdio>
#include <cstring>
#include <queue>
#define INF 1000000 //无穷大
#define MAXN 10 using namespace std; struct ArcNode
{
int to;
int weight;
struct ArcNode *next;
}; queue<int> Q; //队列中的结点为顶点序号
int n; //顶点个数
ArcNode* List[MAXN]; //每一个顶点的边链表表头指针
int inq[MAXN]; //每一个顶点是否在队列中的标志
int dist[MAXN]; //
int path[MAXN]; // void SPFA( int src )
{
int i, u; //u为队列头顶点序号
ArcNode* temp;
for( i=0; i<n; i++ ) //初始化
{
dist[i] = INF;
path[i] = src;
inq[i] = 0;
}
dist[src] = 0;
path[src] = src;
inq[src]++;
Q.push( src );
while( !Q.empty() )
{
u = Q.front( );
Q.pop( );
inq[u]--;
temp = List[u];
while( temp!=NULL )
{
int v = temp->to; if( dist[v] > dist[u] + temp->weight )
{
dist[v] = dist[u] + temp->weight;
path[v] = u;
if( !inq[v] )
{
Q.push(v);
inq[v]++;
}
}
temp = temp->next;
}
}
} int main( )
{
int i, j; //循环变量
int u, v, w; //边的起点和终点及权值
scanf( "%d", &n ); //读入顶点个数n
memset( List, 0, sizeof(List) );
ArcNode* temp;
while( 1 )
{
scanf( "%d%d%d", &u, &v, &w ); //读入边的起点和终点
if( u==-1 && v==-1 && w==-1 ) break;
temp = new ArcNode;
//构造邻接表
temp->to = v;
temp->weight = w;
temp->next = NULL;
if( List[u]==NULL ) List[u] = temp;
else
{
temp->next = List[u];
List[u] = temp;
}
}
SPFA( 0 ); //求顶点0到其它顶点的最短路径
for( j=0; j<n; j++ ) //释放边链表上各边结点所占用的存储空间
{
temp = List[j];
while( temp!=NULL )
{
List[j] = temp->next;
delete temp;
temp = List[j];
}
} int shortest[MAXN]; //输出最短路径上的各个顶点时存放各个顶点的序号
for( i=1; i<n; i++ )
{
printf( "%d\t", dist[i] ); //输出顶点0到顶点i的最短路径长度
//下面代码用于输出顶点0到顶点i的最短路径
memset( shortest, 0, sizeof(shortest) );
int k = 0; //k表示shortest数组中最后一个元素的下标
shortest[k] = i;
while( path[ shortest[k] ] != 0 )
{
k++;
shortest[k] = path[ shortest[k-1] ];
}
k++;
shortest[k] = 0;
for( j=k; j>0; j-- )
printf( "%d→", shortest[j] );
printf( "%d\n", shortest[0] );
}
return 0;
}

Floyd:


#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
#include<vector> using namespace std;
#define INF 1000000 //无穷大
#define MAXN 8 int n; //顶点个数
int Edge[MAXN][MAXN]; //邻接矩阵
int A[MAXN][MAXN]; //
int path[MAXN][MAXN]; // void Floyd( ) //假定图的邻接矩阵和顶点个数已经读进来了
{
int i, j, k;
for( i=0; i<n; i++ )
{
for( j=0; j<n; j++ )
{
A[i][j] = Edge[i][j]; //对a[ ][ ]初始化
if( i!=j && A[i][j]<INF ) path[i][j] = i; //i到j有路径
else path[i][j] = -1; //从i到j没有直接路径
}
}
//从A(-1)递推到A(0), A(1), ..., A(n-1),或者理解成依次将v0,v1,...,v(n-1)作为中间顶点
for( k=0; k<n; k++ )
{
for( i=0; i<n; i++ )
{
for( j=0; j<n; j++ )
{
if( k==i || k==j ) continue;
if( A[i][k] + A[k][j] < A[i][j] )
{
A[i][j] = A[i][k] + A[k][j] ;
path[i][j] = path[k][j];
}
}
}
}
} int main( )
{
int i, j; //循环变量
int u, v, w; //边的起点和终点及权值
scanf( "%d", &n ); //读入顶点个数n
for( i=0; i<n; i++ ) //设置邻接矩阵中每一个元素的初始值为INF
{
for( j=0; j<n; j++ ) Edge[i][j] = INF;
}
for( i=0; i<n; i++ ) //设置邻接矩阵中对角线上的元素值为0
{
Edge[i][i] = 0;
}
while( 1 )
{
scanf( "%d%d%d", &u, &v, &w ); //读入边的起点和终点
if( u==-1 && v==-1 && w==-1 ) break;
Edge[u][v] = w; //构造邻接矩阵
}
Floyd( ); //求各对顶点间的最短路径
int shortest[MAXN]; //输出最短路径上的各个顶点时存放各个顶点的序号
for( i=0; i<n; i++ )
{
for( j=0; j<n; j++ )
{
if( i==j ) continue; //跳过
printf( "%d=>%d\t%d\t", i, j, A[i][j] ); //输出顶点i到顶点j的最短路径长度
//下面代码用于输出顶点0到顶点i的最短路径
memset( shortest, 0, sizeof(shortest) );
int k = 0; //k表示shortest数组中最后一个元素的下标
shortest[k] = j;
while( path[i][ shortest[k] ] != i )
{
k++;
shortest[k] = path[i][ shortest[k-1] ];
}
k++;
shortest[k] = i;
for( int t=k; t>0; t-- )
printf( "%d→", shortest[t] );
printf( "%d\n", shortest[0] );
}
} return 0;
}

版权声明:本文博主原创文章。博客,未经同意不得转载。

最短路径:Dijkstra,Bellman,SPFA,Floyd该算法的实施的更多相关文章

  1. 四大算法解决最短路径问题(Dijkstra+Bellman-ford+SPFA+Floyd)

    什么是最短路径问题? 简单来讲,就是用于计算一个节点到其他所有节点的最短路径. 单源最短路算法:已知起点,求到达其他点的最短路径. 常用算法:Dijkstra算法.Bellman-ford算法.SPF ...

  2. PKU 1932 XYZZY(Floyd+Bellman||Spfa+Floyd)

    题目大意:原题链接 给你一张图,初始你在房间1,初始生命值为100,进入每个房间会加上那个房间的生命(可能为负),问是否能到达房间n.(要求进入每个房间后生命值都大于0) 解题思路: 解法一:Floy ...

  3. 最短路径-Dijkstra算法与Floyd算法

    一.最短路径 ①在非网图中,最短路径是指两顶点之间经历的边数最少的路径. AE:1    ADE:2   ADCE:3   ABCE:3 ②在网图中,最短路径是指两顶点之间经历的边上权值之和最短的路径 ...

  4. 图论——最短路径 Dijkstra算法、Floyd算法

    1.弗洛伊德算法(Floyd) 弗洛伊算法核心就是三重循环,M [ j ] [ k ] 表示从 j 到 k 的路径,而 i 表示当前 j 到 k 可以借助的点:红色部分表示,如果 j 到 i ,i 到 ...

  5. 图论篇3——最短路径 Dijkstra算法、Floyd算法

    最短路径 问题背景:地图上有很多个城市,已知各城市之间距离(或者是所需时间,后面都用距离了),一般问题无外乎就是以下几个: 从某城市到其余所有城市的最短距离[单源最短路径] 所有城市之间相互的最短距离 ...

  6. 最短路径 Dijkstra算法 AND Floyd算法

    无权单源最短路:直接广搜 void Unweighted ( vertex s) { queue <int> Q; Q.push( S ); while( !Q.empty() ) { V ...

  7. 数据结构实验之图论七:驴友计划 ( 最短路径 Dijkstra 算法 )

    数据结构实验之图论七:驴友计划 Time Limit: 1000 ms           Memory Limit: 65536 KiB Submit Statistic Discuss Probl ...

  8. 最短路径——Dijkstra算法和Floyd算法

    Dijkstra算法概述 Dijkstra算法是由荷兰计算机科学家狄克斯特拉(Dijkstra)于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有向图(无 ...

  9. 最短路径Dijkstra算法和Floyd算法整理、

    转载自:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html 最短路径—Dijkstra算法和Floyd算法 Dijks ...

随机推荐

  1. Andriod中绘(画)图----Canvas的使用具体解释

    转载请注明出处:http://blog.csdn.net/qinjuning     因为在网络上找到关于Canvas的使用都比較抽象,或许是我的逻辑思维不太好吧,总是感觉理解起来比較困难, 尤其是对 ...

  2. 新浪SAE数据库信息

    此账号仅能在SAE平台上使用,不能从外部连接我们建议开发者使用SaeMysql操作数据库 如果您想自己实现数据库相关操作,可以使用以下常量: 用户名  : SAE_MYSQL_USER 密 码 : S ...

  3. 谈谈android反编译和防止反编译的方法(转)

    谈谈android反编译和防止反编译的方法(转) android基于java的,而java反编译工具很强悍,所以对正常apk应用程序基本上可以做到100%反编译还原. 因此开发人员如果不准备开源自己的 ...

  4. Hlg 1832 【线段树 && RMQ】.cpp

    题意: 在给出的区间内求出最大买进卖出的差价. 思路: 对于弱数据:维护一个从左到右的最大差价和最小值.即当发现当前值比最小值小的时候更新最小值,否则看一下当前值与之前最小值的差价是否比最大差价大,是 ...

  5. MySQL 模拟Oracle邻接模型树形处理

    数据库对层次结构的处理模型有好多种,能够依据自己的需求来设计模型.当然最简单的也是最easy设计的模型就是所谓的邻接模型.在这方面,其它数据库比方Oracle 提供了现成的分析方法 connect b ...

  6. linux下执行strlwr函数出错:ld returned 1 exit status

    执行strlwr函数时报错.源程序例如以下: #include<stdio.h> #include<string.h> void main() { char s[10]={&q ...

  7. Unity3D开发一个2D横版射击游戏

    教程基于http://pixelnest.io/tutorials/2d-game-unity/ , 这个例子感觉还是比较经典的, 网上转载的也比较多. 刚好最近也在学习U3D, 做的过程中自己又修改 ...

  8. ecshop中getAll ,getOne ,getRow的区别

    ecshop的数据库抽象层其实就是在模仿adodb $GLOBALS['db']->getAll($sql);//以二维关联数组返回所有数据 $GLOBALS['db']->getOne( ...

  9. Android编程 获取网络连接状态 及调用网络配置界面

    获取网络连接状态 随着3G和Wifi的推广,越来越多的Android应用程序需要调用网络资源,检测网络连接状态也就成为网络应用程序所必备的功能. Android平台提供了ConnectivityMan ...

  10. Redhat 6.3中syslog信息丢失

    我们採用Linux的syslog来记录产品的debug log. 调用当中的一个可运行文件.运行完命令之后,查看debug log的信息,竟然从某一条log之后的log都丢失了.多次尝试后,发现每次都 ...