时间复杂度O(n^2)
迪杰斯特拉算法
const int INT = 32767;
const int MAX = 10;
int dis[MAX];
int path[MAX];
int A[MAX][MAX];
void Dijk(int v)
{
bool S[MAX]; // 判断是否已存入该点到S集合中
int n=MAX;
for(int i=1; i<=n; ++i)
{
dis[i] = A[v][i];
S[i] = false; // 初始化
path[i] = v;
}
dis[v] = 0; S[v] = true;
for(int i=2; i<=n; i++)
{
int mindist = INT;
int u = v; // 找出当前未使用的点j的dist[j]最小值
for(int j=1; j<=n; ++j)
if((!S[j]) && dis[j]<mindist)
{
u = j; // u保存当前邻接点中距离最小的点的号码
mindist = dis[j];
}
S[u] = true;
for(int j=1; j<=n; j++)
if((!S[j]) && A[u][j]<INT)
{
if(dis[u] + A[u][j] < dis[j]) //在通过新加入的u点路径找到离v点更短的路径
{
dis[j] = dis[u] + A[u][j]; //更新dist
path[j] = u; //记录前驱顶点
}
}
}
}
用优先队列实现:
struct edge
{
int to;//这条边的终点
int cost;//这条边本身的权值
};
typedef pair<int,int> P; //first是起点到该点的最短距离,second是该顶点的编号
int V;//顶点个数
vector<edge> G[MAXV];
int d[MAXV];//到某点的最短路径
void dijkstra(int s)
{
priority_queue<P,vector<P>,greater<P> > que;//构建升序优先队列
memset(d,INF,sizeof d);
d[s] = 0;
que.push(P(0,s)); //把起点推入队列
while(!que.empty())
{
P p = que.top(); que.pop();
int v = p.second; //顶点的编号
if (d[v] < p.first) continue;//说明这个点是之前压入队的,直接跳过
for(int i = 0; i < G[v].size(); i++)
{//更新到达所有点的路径
edge e = G[v][i];
if (d[e.to] > d[v] + e.cost)
{
d[e.to] = d[v] + e.cost;
que.push(P(d[e.to],e.to));
}
}
}
}