最短路

  • Dijkstra

这个算法感觉跟Prim找最小生成树的思想很像,都是利用贪心和dp的想法,只不过最短路更新的一直是权值和,而Prim每次只更新当前节点接下来延伸的边的最小值。

#include<iostream>
using namespace std;

const int MAXN = 100;
const int LIM = 0x3f3f3f3f;

struct MGragh//邻接矩阵
{
    int matirx[MAXN][MAXN];
    int numVertexes,numEdges;
};

void Djikstra(MGragh G,int v0,int *P,int *D){//P中存放的是最短路顶点前驱,D中存放的是每个顶点的最短路
    int final[MAXN];
    for(int i = 0;i<G.numVertexes;i++){
        final[i] = 0;
        D[i] = G.matirx[v0][i];
        P[i] = 0;
    }
    D[v0] = 0;
    final[v0] = 1;
    for(int v = 1;v<G.numVertexes;v++){//主循环,找出v0到所有顶点的最短路
        int min = LIM;
        int k = -1;
        for(int w = 0;w<G.numEdges;w++){//找出当前状态的最短路
            if(!final[w]&&min<D[w]){
                min = D[w];
                k = w;
            }
        }
        final[k] = 1;
        for(int w = 0;w<G.numVertexes;w++){//更新加入最短路顶点的附近顶点的最短路
            if(!final[w]&&min+G.matirx[k][w]<D[w]){
                D[w] = min+G.matirx[k][w];
                P[w] = k;
            }
        }
    }
}
  • Folyd

Djikstra有一个缺点就是不能找有负边图的最短路,这个算法解决了这个问题,时间复杂度为\(O(n^3)\),一次找到所有顶点的最短路。

const int MAXN = 100;
const int LIM = 100001;

struct Gragh
{
	int matirx[MAXN][MAXN];
	int numVertexs, numEdges;
};

void print(int P[][MAXN], int a, int b)//输出路径
{
    cout<<a<<"->";
    a = P[a][b];
    while(a!=b)
    {
        cout<<a<<"->";
        a = P[a][b];
    }
    cout<<b;
}

void shortestPath_Floyd(Gragh G, int D[][MAXN], int P[][MAXN])
{
	//初始化
	for (int i = 0; i<G.numVertexs; i++)
	{
		for (int j = 0; j<G.numVertexs; j++)
		{
			D[i][j] = G.matirx[i][j];
			P[i][j] = j;
		}
	}
	//主程序
	for (int k = 0; k<G.numVertexs; k++)
		for (int i = 0; i<G.numVertexs; i++)
			for (int j = 0; j<G.numVertexs; j++)
				if (D[i][j]>D[i][k] + D[k][j])
				{
					D[i][j] = D[i][k] + D[k][j];
					P[i][j] = P[i][k];//可用P来迭代找到最短路径
				}
	print(P, 0, 8);
}
posted @ 2019-10-31 16:32  夜烛灯花  阅读(107)  评论(0)    收藏  举报