迪杰斯特拉(优先队列优化)

今天还是搞一下这个迪杰斯特拉的优先队列优化算法吧。对于我们经常用的二维数组来存图的话,只要数据一大,就会超出内存,也可能TLE,所以我们使用优化后的算法。(迪杰斯特拉堆优化)

代码:


#include<iostream>
#include<algorithm>
#include<string.h>
#include<string>
#include<queue>
#include<cstdio>
const int maxn=1005;
const int inf=0x3f3f3f3f;
typedef long long ll;
using namespace std;
typedef pair<int,int> p;

int vis[maxn];
int d[maxn];
int n,m,start;

vector<p>s[maxn];     //存图      
 
void dij(int start)
{
	memset(d,inf,sizeof(d));
	memset(vis,0,sizeof(vis));
	priority_queue<p,vector<p>,greater<p>>q;     //优先队列 
	
	d[start]=0;
	q.push({0,start});
	while(!q.empty())
	{
		p h=q.top();
		q.pop();
		int u=h.second;
		
		if(vis[u])
			continue;
		vis[u]=1;
		for(int i=0;i<s[u].size();i++)
		{
			int v=s[u][i].first;
			int c=s[u][i].second;
			if(!vis[v]&&d[u]+c<d[v])
			{
				d[v]=d[u]+c;
				q.push({d[v],v});
			}
		}
		
	} 
	
}

int main()
{
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		if(n==0&&m==0)
			break;
		for(int i=0;i<n;i++)
			{
				s[i].clear();
			}
		int u,v,x;	
		for(int i=0;i<m;i++)
		{
			cin>>u>>v>>x;
			s[u].push_back({v,x});
    	  	s[v].push_back({u,x});	
		}	
		int a,b;
		scanf("%d%d",&a,&b);
		dij(a); 
		
		if(d[b]!=inf)
			printf("%d\n",d[b]);
		else
			printf("-1\n");
		
	}
	
	return 0;
}

说一下,我们首先得存图,我们使用邻接表来实现存图,二维vector 来实现,然后我们在后面的优先队列中,我们可以使用结构体重载一下,也可以直接用pair +优先队列排序,两种方法都可以使用,直接使用一个pair 就比较再来一个结构体简单。 其中的原理就是跟迪杰斯特拉一模一样,就是现将起始点压入队列中,然后再看图,从这个点出去的一个最小权值的点,然后从这个点再连接到其他的点 ,我们更新权值,看是直接到那个点短,还是先走一个点再到那个点快,更新一下数据,然后再将那个点压入队列中,然后再进行后面的操作,就这样一直一直进行,直到最后将所有点都标记完全结束。

发布了123 篇原创文章 · 获赞 83 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/tsam123/article/details/89715463