单源最短路
一、Dijkstra算法(O(n^2))
应用条件:
1、无环,2、无负权边 3、起点必须已知 4、节点个数不能过大
Dijkstra 算法主要解决的是单源最短路径问题。它的时间复杂度一般是o(n^2) ,因此相对于Floyd算法速度上有极大的优势,可以处理更多的数据。
思路:
1、遍历n次,确定n个点的最短距离
2、在每次遍历中,先找到没有确定最短距离的且到目前到初始点最短的点
3、用这个点去更新其它点
int dijkstra()
{
memset(dist, 0x3f, sizeof dist);
dist[1] = 0;//dist[]存放第i个点到初始点的最短距离
for (int i = 0; i < n ; i ++ )//遍历n次,求出n个点的最短距离
{
int t = -1;//还没有确定到集合最短的点
for (int j = 1; j <= n; j ++ )
if (!st[j] && (t == -1 || dist[t] > dist[j]))
t = j;
for (int j = 1; j <= n; j ++ )
dist[j] = min(dist[j], dist[t] + g[t][j]);
st[t] = true;
}
if (dist[n] == 0x3f3f3f3f) return -1;
return dist[n];
}
二、Bellman-Ford算法
应用条件:
单源最短路径(从源点s到其它所有顶点v);
有向图&无向图(无向图可以看作(u,v),(v,u)同属于边集E的有向图);
边权可正可负(如有负权回路输出错误提示);
struct Edge
{
int a, b, c;
}edges[M];
int bf()
{
memset(dist,0x3f,sizeof dist);
for(int k=1;k<n;k++)//最多经过k次中转
{
memcpy(last, dist, sizeof dist);//备份上一次
for(int i=1;i<=m;i++)
{
auto e=eage[i];
dist[e.b]=min(dist[e.b],dist[e.a]+e.w);
}
}
}
多源最短路
Floyd算法
void flyid()
{
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
}
int fun()
{
memset(dist,0x3f,sizeof dist);
dist[1]=0;
queue<int> q;
q.push(1);
st[1]=1;
while(q.size())
{
int t=q.front();
q.pop();
st[1]=0;
for(int i=h[t];i!=-1;i=ne[i])
{
int j=e[i];
if(dist[j]>dist[t]+w[i])
{
dist[j]=dist[t]+w[i];
if(st[j]==0)
{
q.push(j);
st[j]=1;
}
}
}
}
if(dist[n]==0x3f3f3f3f)
return -1;
else
return dist[n];
}