这个算法适用于权值为非负的图的单源最短路径
解释以后再补充,废话不多说先模板
这是以邻接矩阵来储存的算法:
const int INF=0x3f3f3f3f;//无穷
bool vis[maxn];//判断节点是否已经被访问
ll d[maxn];//每个点到1这个点的最短距离
int way[maxn][maxn];//路径,以邻接矩阵形式
int path[maxn];//储存的路径,path[i]为由i到path[i],用while遍历
/*
最短路径path的遍历方法:
int pos=n;
while(true)
{
if(pos==1)break;
//----------
//此处添加操作
//----------
pos=path[pos];
}
*/
int n;
bool once=true;
void Dijkstra()
{
memset(vis,false,sizeof(vis));
d[1]=0;//这里把1搞成0就是要求其它点到1的最短距离,改成其它等于零可以求到其它点的最短距离
for(int i=2;i<=n;i++)//这里让它们初始为无穷
d[i]=INF;
for(int i=1;i<=n;i++)
{
int x,m=INF;//x离1节点最近但是没有被访问的点,m记录这个点到1的最短距离
for(int j=1;j<=n;j++)//这里遍历来替换,得到x,m
{
if(!vis[j]&&d[j]<=m)
{
m=d[j];
x=j;
}
}
vis[x]=true;//标记已经访问
for(int y=1;y<=n;y++)
{
if(way[x][y]==0)continue;//在这里,为0代表没有路,也可以初始化所有路为INF
if(d[y]>d[x]+way[x][y])//更新被选中x相邻的点的值,确保最小
{
d[y]=d[x]+way[x][y];
path[y]=x;//储存一条最短路径,并且是倒序
}
}
}
}
可以用邻接表来,有些时候会省时间:
const int INF=0x3f3f3f3f;
bool vis[maxn];
ll d[maxn];
int path[maxn];
int n;
typedef struct node
{
int aim;//这条路的终点
int dis;//这条路的长度
};
vector<node> way[maxn];
bool once=true;
void Dijkstra()
{
memset(vis,false,sizeof(vis));
d[1]=0;
for(int i=2;i<=n;i++)
d[i]=INF;
for(int i=1;i<=n;i++)
{
int x,m=INF;
for(int j=1;j<=n;j++)
{
if(!vis[j]&&d[j]<=m)
{
m=d[j];
x=j;
}
}
vis[x]=true;
for(int j=0;j<way[x].size();j++)//不用判断路是否存在了,直接列出所有路
{
if(d[way[x][j].aim]>d[x]+way[x][j].dis)
{
d[way[x][j].aim]=d[x]+way[x][j].dis;
path[way[x][j].aim]=x;
}
}
}
}