记从起点s出发到顶点i的最短距离为d[i]。则下述等式成立:
d[i] = min{d[j] + (从j到i的边的权值)|e = (j,i)∈E}
Dijkstra算法的基本思路:
(1)找到最短距离已经确定的顶点,从它出发更新相邻顶点的最短距离。
(2)此后不需要再关心1中的“最短距离已经确定的顶点”。
对于最小生成树问题,有一个算法和Dijkstra算法十分相似(实现代码几乎一模一样)。
它们都是从某个顶点出发,不断添加边的算法。
Prim算法基本思想是:
假设一颗只包含一个顶点v的树T,然后贪心地选取T和其他顶点之间相连的最小权值的边,并把它加到T中。不断进行这个操作,即可得到最小生成树。
d[i] = min{d[j] + (从j到i的边的权值)|e = (j,i)∈E}
Dijkstra算法的基本思路:
(1)找到最短距离已经确定的顶点,从它出发更新相邻顶点的最短距离。
(2)此后不需要再关心1中的“最短距离已经确定的顶点”。
int cost[MAX_V][MAX_V];
int d[MAX_V];
bool used[MAX_V];
int V;
void dijksra(int s)
{
fill(d, d + V, INF);
fill(used, used + V, false);
d[s] = 0;
while (true)
{
int v = -1;
for (int u = 0; u < V; u++)
if (!used[u] && (v == -1 || d[u] < d[v]))
v = u;
if (v == -1)
break;
used[v] = true;
for (int u = 0; u < V; u++)
d[u] = min(d[u], d[v] + cost[v][u]);
}
}
对于最小生成树问题,有一个算法和Dijkstra算法十分相似(实现代码几乎一模一样)。
它们都是从某个顶点出发,不断添加边的算法。
Prim算法基本思想是:
假设一颗只包含一个顶点v的树T,然后贪心地选取T和其他顶点之间相连的最小权值的边,并把它加到T中。不断进行这个操作,即可得到最小生成树。
int cost[MAX_V][MAX_V];
int mincost[MAX_V];
bool used[MAX_V];
int V;
void prim(int s)
{
fill(mincost, mincost + V, INF);
fill(used, used + V, false);
mincost[0] = 0;
int res = 0;
while (true)
{
int v = -1;
for (int u = 0; u < V; u++)
if (!used[u] && (v == -1 || mincost[u] < mincost[v]))
v = u;
if (v == -1)
break;
used[v] = true;
res += mincost[v];
for (int u = 0; u < V; u++)
mincost[u] = min(mincost[u], mincost[v] + cost[v][u]);
}
return res;
}