Dijkstra算法(单源无负权图)
//适用于边权为正的情况,单源最短路问题
//时间复杂度为O(V*V+E)
//算法思路:设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合(用S表示,初始时S中只有一个源点,以后每求得一条最短路径 , 就将加入到集合S中,直到全部顶点都加入到S中,算法就结束了)
//不断的维护一个dis数组,最后得到的dis数组中dis[i]就是源点到图中节点i的最短路径的长度
//记录vis数组判断当前点是否访问过
int mp[n][n],dis[n],vis[n];
void init()
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i==j)
mp[i][j]=0;
else
mp[i][j]=INF;
}
}
}
int djs(int st,int ed)
{
for(int i=1;i<=n;i++)
{
dis[i]=mp[st][i];
vis[i]=0;
}
vis[st]=1;
for(int i=1;i<n;i++)
{
int minl=INF;
int next=-1; //确定下一个点
for(int j=1;j<=n;j++)
{
if(vis[j]==0&&dis[j]<minl)
{
minl=dis[j];
next=j;
}
}
if(next==-1) //当前已不存在点
continue;
vis[next]=1;
for(int j=1;j<=n;j++)
{
if(vis[j]==0) //vis[j]=1已为最短路径
dis[j]=min(dis[j],dis[next]+mp[next][j]); //以next为中间点进行松弛
}
}
return dis[ed];
}
SPFA,Bellman-Ford的队列优化(单源有负权图)
//玄学时间复杂度,O(E)-O(VE)之间
//假设有一个点刚刚被优化了,我们可以很明显的发现,针对这条边, 也就只有这条边的出边上的终点才可以继续被优化
//这就给了我们启示, 其实我们可以再维护一个队列,一个点如果被优化过了,那么就进队列。
int n,m;
int mp[n][n],dis[n],vis[n];
void init()
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i==j)
mp[i][j]=0;
else
mp[i][j]=INF;
}
}
}
int spfa(int st,int ed)
{
for(int i=1;i<=n;i++)
{
dis[i]=INF;
vis[i]=0;
}
dis[st]=0;
queue<int>q;
q.push(st);
vis[st]=1;
while(!q.empty())
{
int now=q.front();
q.pop();
vis[now]=0;
for(int i=1;i<=n;i++)
{
if(dis[i]>dis[now]+mp[now][i])
{
dis[i]=dis[now]+mp[now][i];
if(vis[i]==0)
{
q.push(i);
vis[i]=1;
}
}
}
}
return dis[ed];
}
Floyd算法(多源无负权图)
//通过邻接矩阵跑出所有点之间的最短路,时间复杂度O(n^3),空间复杂度O(n^2)
//d[i][j]表示i到j的最短路径长度
//初始化:d[i][i]=0,点到点有路按正常权值初始化,其余为INF
#include<bits/stdc++.h>
#define INF 1e9
using namespace std;
int mp[105][105],dis[105][105];
int n,m;
void init()
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i==j)
dis[i][j]=0;
else
dis[i][j]=INF;
}
}
}
void Floyd()
{
for(int k=1;k<=n;k++)//枚举以k为中间点的所有点的最短路
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
}
}
}
int main()
{
int u,v,d;
scanf("%d%d",&n,&m);
init();
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&d);
mp[u][v]=d;
mp[v][u]=d'
}
scanf("%d%d",&s,&e);
Floyd();
printf("%d\n",dis[s][e]);
}