今天还是搞一下这个迪杰斯特拉的优先队列优化算法吧。对于我们经常用的二维数组来存图的话,只要数据一大,就会超出内存,也可能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 就比较再来一个结构体简单。 其中的原理就是跟迪杰斯特拉一模一样,就是现将起始点压入队列中,然后再看图,从这个点出去的一个最小权值的点,然后从这个点再连接到其他的点 ,我们更新权值,看是直接到那个点短,还是先走一个点再到那个点快,更新一下数据,然后再将那个点压入队列中,然后再进行后面的操作,就这样一直一直进行,直到最后将所有点都标记完全结束。