`
plussai
  • 浏览: 88739 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

单源最短路径SPFA---zoj3146

阅读更多

          针对Bellman-Ford算法效率比较低的问题,SPFA是用一个队列来进行维护。初始时将源加入队列。每次从队列中取出一个元素,并对所有与他相邻的点进行松弛,若某个相邻的点松弛成功,则将其入队。直到队列为空时算法结束。它可以在O(kE)的时间复杂度内求出源点到其他所有点的最短路径,有办法证明对于通常的情况,k在2左右。

         值得注意的一点是,如果某个点进入队列的次数超过V次则图中存在负环(SPFA无法处理带负环的图)。

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;
class node
{
public:
	int r,c;
	node(){}
	node(int r,int c):r(r),c(c){}
};
class edge
{
public:
	int sr,sc,er,ec;
	int cost;
	edge(){}
	edge(int sr,int sc,int er,int ec,int cost):sr(sr),sc(sc),er(er),ec(ec),cost(cost)
	{
	}
};
int n,m,r,c;
int map[31][31];
int dist[31][31];
int flag[31][31];
const int maximum=1<<30;
vector<edge>a[31][31];

void init()
{
	for(int i=0;i<n;i++)
	for(int j=0;j<m;j++)
	a[i][j].clear();
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
		{
			if(map[i][j]==0)
				continue;
			int d;
			int west=j-map[i][j];
			if(west<0)
			{
				edge e(i,j,i,0,map[i][j]);
				a[i][j].push_back(e);	
			}
			else
			{
				edge e(i,j,i,west,map[i][j]);
				a[i][j].push_back(e);
			}		
			int east=j+map[i][j];
			if(east>=m)
			{
				edge e(i,j,i,m-1,map[i][j]);
				a[i][j].push_back(e);
			}
			else
			{
				edge e(i,j,i,east,map[i][j]);
				a[i][j].push_back(e);
			}
			int north=i-map[i][j];
			if(north<0)
			{
				edge e(i,j,0,j,map[i][j]);
				a[i][j].push_back(e);
			}
			else
			{
				edge e(i,j,north,j,map[i][j]);
				a[i][j].push_back(e);
			}
			int south=i+map[i][j];
			if(south>=n)
			{
				edge e(i,j,n-1,j,map[i][j]);
				a[i][j].push_back(e);
			}
			else
			{
				edge e(i,j,south,j,map[i][j]);
				a[i][j].push_back(e);
			}	
		}
	}		
}
bool SPFA()
{
	for(int i=0;i<n;i++)
	for(int j=0;j<m;j++)
		dist[i][j]=maximum;
	memset(flag,0,sizeof(flag));
	dist[r-1][c-1]=0;
	queue<node>q;
	q.push(node(r-1,c-1));
	flag[r-1][c-1]=1;;
	while(!q.empty())
	{
		node n=q.front();
		q.pop();
		int row=n.r;
		int col=n.c;
		flag[row][col]=0;
		int size=a[row][col].size();
		for(int i=0;i<size;i++)
		{
			int startr=(a[row][col])[i].sr;
			int startc=(a[row][col])[i].sc;
			int endr=(a[row][col])[i].er;
			int endc=(a[row][col])[i].ec;
			int cost=(a[row][col])[i].cost;
			if(dist[startr][startc]!=maximum&&dist[startr][startc]+cost<dist[endr][endc])
			{
				dist[endr][endc]=dist[startr][startc]+cost;
				if(flag[endr][endc]==0)
				{
				
					q.push(node(endr,endc));
					flag[endr][endc]==1;
				}		
			}	
		}	
	}
	return true;
}
int main()
{
	while(cin>>n>>m>>r>>c)
	{
		int fr,fc;
		for(int i=0;i<n;i++)
		for(int j=0;j<m;j++)
		{	
			cin>>map[i][j];
			if(map[i][j]==0)
			{
				fr=i;
				fc=j;	
			}
		}
		init();
		SPFA();
		if(dist[fr][fc]!=maximum)
		cout<<dist[fr][fc]<<endl;
		else
		cout<<"No solution"<<endl;
	}	
}

   

       

     

分享到:
评论

相关推荐

    单源最短路径--分支限界法

    单源最短路径--分支限界法

    用贪心算法解单源最短路径问题

    用贪心算法解单源最短路径问题 明确单源最短路径问题的概念;利用贪心算法解决单源最短路径问题;并通过本例熟悉贪心算法在程序设计中的应用方法。

    分支限界法求解单源最短路径.zip

    1.分支限界法求解单源最短路径 2.C++源码+程序说明文档 3.源码带详细注释

    单源最短路径问题C++代码

    经典算法单源最短路径经典算法单源最短路径经典算法单源最短路径经典算法单源最短路径经典算法单源最短路径

    单源最短路径-贪心算法

    关于单源最短路径的问题非常典型,这里没有给出分析与证明,仅仅给出了实现。 需要指出的是,许多实现仅给出了最短路径的长度,而没有给出“最短路径”,这里用给出了实现。 如程序中那样,定义一个数组p[N],其中...

    用Dijkstra算法求图中单源最短路径

    A、掌握图中单源最短路径的概念; B、掌握Dijkstra算法的原理;

    单源最短路径实验报告

    单元最短路径,为广大计算机专业学生算法所需实验报告而准备

    分支限界法求解单源最短路径

    有很长时间没有上传了,主要是因为这些天出了些小事。这个是用分支限界法求解单源最短路径问题的算法。

    单源最短路径

    单源最短路径C语言实现,简单易懂,适合算法学习

    分支限界法-单源最短路径

    分支限界法 (1)描述:采用广度优先产生状态空间树的结点,并使用剪枝函数的方法称为分枝限界法。 所谓“分支”是采用广度优先的策略,依次生成扩展结点的所有分支(即:儿子结点)。 所谓“限界”是在结点扩展...

    动态规划求单源最短路径.doc

    算法设计与分析课内实验——动态规划求单源最短路径。文档很齐全,包括算法分析过程和源代码(java语言eclipse环境)

    单源最短路径问题

    在算法中,利用结点间的控制关系进行剪枝。从源顶点s出发,2条不同路径到达图G的同一顶点。由于两条路径的路长不同,因此可以将路长长的路径所对应的树中的结点为根的子树剪去。

    基于贪心法求解单源最短路径问题.docx

    基于贪心法求解单源最短路径问题 完整实验报告,结尾有实验代码

    贪心算法法-单源最短路径 java

    给定一个带权有向图 G=(V,E) ,其中每条边的权是一个整数。另外,还给定 V 中的一个顶点,称为源。现在我们要计算从源到所有其他各顶点的最短路径长度。这里的长度是指路上各边权...这个问题通常称为单源最短路径问题。

    python实现有向图单源最短路径迪杰斯特拉 算法

    用python实现迪杰斯特拉算法,单源最短路径,有向图权值无负值,用邻接矩阵来存储有向图,实现路径存储和路径打印

    单源最短路径(贪心算法)报告.doc

    算法设计与分析实验报告,附已通过源码,供学习参考,共勉♪ 目录摘要如下: 1.问题描述 2.实验目的 3.实验原理 4.实验设计 ...(包括输入格式、算法、输出格式) ...(除了截图外,实验结果还用图表进行了分析) ...

    贪心算法 Dijkstra 单源最短路径

    用C++实现的贪心算法 Dijkstra 单源最短路径,并包含大量的注释,对理解程序很有帮助

    算法分析中单源最短路径问题的C++代码

    这是算法分析中实现单源最短路径问题的C++程序

    Dijkstra求单源最短路径

    Dijstra算法用于求解单源最短路径问题,即在图中求出给定顶点到其它任一顶点的最短路径。

    用Dijkstra算法实现单源最短路径问题

    用Dijkstra算法实现单源最短路径问题。 第一行:n。代表n个顶点。其中第一个顶点为源点 第二行:c11 c12 c13....c1n (以下n行合起来为n*n的权矩阵,cij代表了i点到j点的边的权值,-1代表无穷大.每行n个数,数与...

Global site tag (gtag.js) - Google Analytics