带权有向图单源最短路径(Dijkstra算法)

来源:互联网 发布:人工智能 电影免费 编辑:程序博客网 时间:2024/06/06 08:41

最短路径的第一类问题
求从单个源点到其余各顶点的最短路径。这是一种贪心策略,不可以存在负权边。

算法简介
给定带权有向图G和源点v0,求从源点v0到G中其余各顶点的最短路径。迪杰斯特拉算法是对有权图进行搜索,但是如果引用于无权图或者是权值相等的图,就是广度优先搜索。(注意是有向图)

算法描述
对于网N=(V,E),将N中的顶点分成两组:
第一组S:已求出的最短路径的终点集合(初始时只含有v0)
第二组V-S:尚未求出最短路径的终点集合(初始时为V-{v0})
算法将按照各顶点与v0间的最短路径长度递增的次序,逐个将集合V-S中的顶点加入到集合S中。在这个过程中,总保持从v0到集合S中每一个顶点的路径长度始终不大于到集合V-S中各顶点的路径长度。
每当加入一个新的顶点到S集合中,对于V-S集合的顶点而言,多了一个中转结点
,因此要对V-S集合中的各个顶点的最短路径的长度进行更新。

算法代码

const int INF = 0x3f3f3f3f;  //防止后面溢出,INF不能太大const int maxn = 1000+5; //点的个数bool visit[maxn]; //bool[i]表示是否确定过最短路径int map[maxn][maxn]; //用邻接矩阵的方式来存储图int distance[maxn]; //distance[i]表示v0到vi的最短路径void Dijkstra(int n,int beg) //beg表示源结点{    for(int i=1;i<=n;i++)    {        distance[i] = map[beg][i];        visit[i] = false;    }    visit[beg] = true;    distance[beg] = 0;    int v;    for(int i=2;i<=n;i++)  //对其他的n-1个点进行操作    {        int Min = INF;        for(int j=1;j<=n;j++)        {            //遍历左右结点,找到离当前源点的最短路径            if(!visit[j] && distance[j] < Min)            {                v = j;                Min = distance[j];            }        }        visit[j] = true; //加入S集合        //松弛操作        for(int j=1;j<=n;j++)        {            if(!visit[j] && Min + map[v][j] < distance[j]) //利用这次加入的边的Min进行对V-S集合distance的更新            //每一次MIn是S中最大的,因为之前加入的比后来的小                distance[j] = Min + map[v][j];        }    }}
0 0