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

原创 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. 迪杰斯特拉算法 求从源点到其余各点的最短路径 依最短路径的长度递增的次序求得...

Dijkstra算法和Floyd算法的实现

摘 要 在实际生活当中,我们需要知道从一个城市到达另一个城市的最短路径,在旅行时可以减少在路途中的时间。路由器的路由表的更新也需要知道两个路由之间的最短距离。很多的关于两点之间的最短路径问题都可...

Dijkstra算法、Floyd算法的区别与联系,并由此谈到greedy和DP

首先,Dijkstra算法与Floyd算法都是广度优先搜索的算法。都可以用来求单源点到其他所有点的最短路径。那么这两者的原理分别是怎样?彼此又有什么区别呢?求此有向图中起点1到其他所有点的最短距离在本...

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

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

【poj 2976】 Dropping tests 二分(分数优化)

题目:http://poj.org/problem?id=2976Dropping testsTime Limit: 1000MS Memory Limit: 65536K Total Subm...
  • ALPS233
  • ALPS233
  • 2016年06月01日 18:42
  • 2486

并查集(Union-Find)算法介绍

本文主要介绍解决动态连通性一类问题的一种算法,使用到了一种叫做并查集的数据结构,称为Union-Find。 更多的信息可以参考Algorithms 一书的Section 1.5,实际上本文也就是...

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

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

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

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

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

最短路径: 对于网图来说,最短路径,是指两顶点之间经过的边上权值之和最少的路径,并且我们称路径上的第一个顶点是源点,最后一个顶点是终点。 对于非网图来说,完全可以理解为所有边的权值都为1的网。 ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:迪杰斯特拉算法与弗洛伊德算法
举报原因:
原因补充:

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