迪杰斯特拉算法与弗洛伊德算法

原创 2016年08月30日 15:29:26

// mydjstl.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>

using namespace std;

#pragma comment(linker, "/STACK:10000000 ")//扩大栈的大小,默认栈的大小为1M,这时maxnum=1000的话会超过栈的承受能力,因此设置栈大小为10M后面的10000000表示10Mb

#define maxnum 1000
#define maxint 99999

int mydjstl(int s,int e,int num,int *dist,int c[maxnum][maxnum])
{
	int res=0;
	int sa[maxnum]={0};//查看节点i是否在已遍历节点集合中
	for(int i=1;i<=num;i++)//初始化dist数组距离
	{
		dist[i]=c[s][i];
	}
	sa[s]=1;//首节点设置为已遍历集合中
	
	for(int i=2;i<=num;i++)//进行n-1次循环
	{
		int u=s;
		int tmp=maxint;
		for(int i=1;i<=num;i++)
		{
			if(!sa[i] && dist[i]<tmp)//对每一个未遍历的节点进行遍历,找到所有未遍历结点中距离首节点中最小的节点,然后将该节点加入到已遍历集合中
			{
				tmp=dist[i];
				u=i;
			}
		}
		sa[u]=1;
		for(int i=1;i<=num;i++)//更新dist数组
		{
			if(!sa[i] && c[i][u]<maxint)
			{
				int newdist = dist[u]+c[i][u];
				if(dist[i]>newdist)
				{
					dist[i]=newdist;
				}
			}
		}
	}
	res=dist[e];


	return res;
}

int _tmain(int argc, _TCHAR* argv[])
{
	freopen("input.txt","r",stdin);
	int dist[maxnum];
	int c[maxnum][maxnum];
	int n,line;

	cin>>n;
	cin >>line;
	int p,q,len;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			c[i][j]=maxint;
		}
	}
	for(int i=1;i<=line;++i)
	{
		cin>>p>>q>>len;
		if(len<c[p][q])
		{
			c[p][q]=len;
			c[q][p]=len;
		}
	}
	for(int i=1;i<=n;i++)
		dist[i]=maxint;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			printf("%8d",c[i][j]);
		}
		cout<<endl;
	}

	int res=mydjstl(4,3,n,dist,c);//输出节点4到节点3的路径
	cout<<res<<endl;


	return 0;
}

迪杰斯特拉老爷子的算法在在网络中被大量使用,说明一下;

迪杰斯特拉算法就是从首节点出发进行遍历,找到距离最小的下一节点,加入已经遍历的集合当中,代码说明一切:

注意迪杰斯特拉算法不能存在负权值边,因为

dijkstra由于是贪心的,每次都找一个距源点最近的点(dmin),然后将该距离定为这个点到源点的最短路径(d[i]<--dmin);但如果存在负权边,那就有可能先通过并不是距源点最近的一个次优点(dmin'),再通过这个负权边L(L<0),使得路径之和更小(dmin'+L<dmin),则dmin'+L成为最短路径,并不是dmin,这样dijkstra就被囧掉了。

弗洛伊德算法点与点的距离放在一个二维矩阵内,
// myfloyd.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>

using namespace std;

#define maxint 9999
#define maxnum 1000

int c[maxnum][maxnum];

void floyd(int num)
{
	int i=0,j=0,k=0;
	for(k=1;k<=num;k++)
	{
		for(i=1;i<=num;i++)
		{
			for(j=1;j<=num;j++)
			{
				if(c[i][j]>c[i][k]+c[k][j])
				{
					c[i][j]=c[i][k]+c[k][j];//结果就在矩阵中,如果i->k->j的距离小于i->j,那么将k加入到i与j之间
				}
			}
		}
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	freopen("input.txt","r",stdin);
	int dist[maxnum];
	
	int n,line;

	cin>>n;
	cin >>line;
	int p,q,len;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			if(i==j)
				c[i][j]=0;
			else
				c[i][j]=maxint;
		}
	}
	for(int i=1;i<=line;++i)
	{
		cin>>p>>q>>len;
		if(len<c[p][q])
		{
			c[p][q]=len;
			//c[q][p]=len;
		}
	}
	for(int i=1;i<=n;i++)
		dist[i]=maxint;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			printf("%8d",c[i][j]);
		}
		cout<<endl;
	}
	floyd(n);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			printf("%8d",c[i][j]);
		}
		cout<<endl;
	}


	return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

图(最短路径算法————迪杰斯特拉算法和弗洛伊德算法)

一: 最短路径算法 1. 迪杰斯特拉算法 2. 弗洛伊德算法 二: 1. 迪杰斯特拉算法 求从源点到其余各点的最短路径 依最短路径的长度递增的次序求得...

最短路之弗洛伊德and迪杰斯特拉

首先来两段代码: 弗洛伊德核心代码:                 for(k=1;k for(i=1;i for(j=1;j if(dis[i][j]>dis[i][k]+dis[k][...

C++代码,数据结构-最短路径(两种情况)(迪杰斯特拉算法和弗洛伊德算法)

1.单源的,从有向图某个源点, 到其他点的最短路径 利用算法迪杰斯特拉算法; Dijkstra算法的基本思想: 一个辅助数组D[max_v];每个D[i]表示当前所知源点到vi的最短路径的长度 一个辅...

深度优先DFS和广度优先BFS,破圈法,拓扑序列,prim,克鲁斯卡尔等生成算法(需要用到并查集)迪杰斯特拉算法和弗洛伊德的总结

1.有向图:比较好 2.无向图是变态的有向图,需要注意度和节点之类的比如MST,最小生成树利用破圈法生成,关联的度为1的无向图节点肯定不是回路(不知道对不。。),1.找到图中的一个圈。2.删除其中的...

数据结构看书笔记(十)—— 求最短路径问题之--迪杰斯特拉(Dijkstra)算法和弗洛伊德(Floyd)算法

最短路径: 对于网图来说,最短路径,是指两顶点之间经过的边上权值之和最少的路径,并且我们称路径上的第一个顶点是源点,最后一个顶点是终点。 对于非网图来说,完全可以理解为所有边的权值都为1的网。 ...

最短路径算法:迪杰斯特拉(Dijkstra)和弗罗伊德(Floyd)

关于迪杰斯特拉(Dijkstra)和弗罗伊德(Floyd)算法的思想,严蔚敏老师书上,还有网络上一些博客,讲的比较清楚了,这里只一并给出其实现及驱动源码,注释也比较详细。算法思想非本人原创,只是做一些...

迪杰斯特拉算法

Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。Dijkstra算法能得出最短路径的最优...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)