简单介绍
迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题。迪杰斯特拉算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。
普通模版
时间复杂度O(n2)
void Dijkstra()
{
memset(dis,127,sizeof(dis));
memset(exist,0,sizeof(exist));
int x,y,z;
int i,j;
int cmin;
dis[1]=0;
for(j=1;j<=n;j++) {
cmin=INF;
for(i=1;i<=n;i++) {
if(exist[i]) continue; //不考虑已经选的点
if(dis[i]<cmin) { cmin=dis[i]; x=i; } //选出dis最小的点
}
exist[x]=true;//选中
for(i=one[x];i;i=Next[i]) {//scan all the edges;
y=ver[i]; z=edge[i];
if(dis[y]>dis[x]+z) //improve node y;
dis[y]=dis[x]+z;
}
}
return;
}
堆优化模板
时间复杂度O((n+m)logn)
核心代码
priority_queue< pair<int,int> > q;
//大根堆(优先队列),pair的第二维为节点编号;
//pair的第一维为dis的相反数,利用相反数变成小根堆;
//默认对pair的第一维排序;
void Dijkstra()
{
memset(dis,127,sizeof(dis));
memset(exist,0,sizeof(exist));
while(q.size()) q.pop();
int u,x,y,z;
dis[1]=0;
q.push(make_pair(0,1));
while(!q.empty()) {
x=q.top().second; q.pop();
if(exist[x]) continue;//已经被选中
exist[x]=true;//选中
for(int i=one[x];i;i=Next[i]) {//scan all the edges;
y=ver[i]; z=edge[i];
if(dis[y]>dis[x]+z) { //relax node y;
dis[y]=dis[x]+z;
q.push(make_pair(-dis[y],y)); //push node y;
}
}
}
return;
}
完整代码
#include<bits/stdc++.h>
using namespace std;
priority_queue< pair<int,int> > q;
//大根堆(优先队列),pair的第二维为节点编号;
//pair的第一维为dis的相反数,利用相反数变成小根堆;
//默认对pair的第一维排序;
const int MAXN=10000*2+5;
const int MAXM=10000+5;
int dis[MAXN];
bool exist[MAXN];
int one[MAXN],ver[MAXN],edge[MAXN],Next[MAXN],adj[MAXN];
int n,m;
int tot=0;
/*输入n, m,表示 n个城市和 m条路;
接下来m行,每行a b c,表示城市a与城市b有长度为c的路。*/
void add(int a,int b,int c)//from a to b;
{
tot++;
if(one[a]==0) one[a]=tot;
Next[adj[a]]=tot; adj[a]=tot;
edge[tot]=c;
ver[tot]=b;
return;
}
void Init()
{
int i,j;
int a,b,c;
cin>>n>>m;
for(i=1;i<=m;i++) {
scanf("%d%d%d",&a,&b,&c);
add(a,b,c); //把一条无向边当两条有向边存
add(b,a,c);
}
return;
}
void Dijkstra()
{
memset(dis,127,sizeof(dis));
memset(exist,0,sizeof(exist));
while(q.size()) q.pop();
int u,x,y,z;
dis[1]=0;
q.push(make_pair(0,1));
while(!q.empty()) {
x=q.top().second; q.pop();
if(exist[x]) continue;//已经被选中
exist[x]=true;//选中
for(int i=one[x];i;i=Next[i]) {//scan all the edges;
y=ver[i]; z=edge[i];
if(dis[y]>dis[x]+z) { //relax node y;
dis[y]=dis[x]+z;
q.push(make_pair(-dis[y],y)); //push node y;
}
}
}
return;
}
int main()
{
// freopen("1.in","r",stdin);
Init();
Dijkstra();
if(dis[n]!=dis[0]) cout<<dis[n];
else cout<<"-1";
return 0;
}