问题
求解一个点到图中所有点的最短距离,稠密图、不能含有负权
Dijkstra算法
基本思想
每次在未确定最小距离的点集中找距离源点src最近的点,然后以该点为中转点更新源点到其他点的距离
算法步骤
1、初始化minDis[i]=infy(很大的值),minDis[src]=0;使用isVisited[i]来表示minDis[i]是否已经确定
2、在未确定点集中寻找minDis[i]最小的结点u,将u加入到确定的点集中(即isVisited[u]=true)
3、更新所有以u为起点的边的终点v到源点s的距离(更新的方法:如果dis[v]<dis[u]+e[u][v],就更新dis[v]=dis[u]+e[u][v])
4、重复2、3步骤直到所有点都确定
时间复杂度:n表示结点数,m表示图中边数
邻接矩阵存图:O(n^2)
邻接表存图:O((m+n)*log(n))
Java实现(邻接表)
class Edge{
int to;
int dis;
}
class Traffic{
int src;
int N;
int M;
int[] minDis;
Vector<Edge>[] graph;
void init(){
minDis = new int[N];
graph = new Vector[N];
for (int i = 0; i < N; i++)
graph[i] = new Vector<Edge>();
}
void Dijkstra(){
//initialization
boolean[] isVisited = new boolean[N];
for (int i = 0; i < N; i++)
minDis[i] = 1000;
minDis[src]= 0;
int num = N;
while (num-- > 0){
int u=0,min = 1005;
for (int i = 0; i < N; i++) {
if (!isVisited[i] && minDis[i] < min) {
min = minDis[i];
u = i;
}
}
isVisited[u] = true;
for (int i = 0; i < graph[u].size(); i++) {
Edge edge = graph[u].get(i);
if(minDis[edge.to]>minDis[u]+edge.dis)
minDis[edge.to] = minDis[u] + edge.dis;
}
}
}
}