算法执行步骤详解
step 1
初始时我们有两个集合A,B,集合A中是所有的点,B中最开始无点
step 2
向B中加入起始点,A中删除该点,并更新该点可到范围内的点的起始距离
step3
随后在B中加入A中的距离起始点最小的点,并从A中删除,然后对这个数能到达的数进行一次更新,重复上面的操作直到目标的点在我们的B中
本质是一种BFS
void dijstra(int start,int end)
{
q.push_back(start);
for(int i = 1;i <= n;i++) dis[i] = inf;
for(int i = Head[start];i; i = E[i].next) {dis[to] = E[i].value;}
while(1)
{
int Min = inf;
int minstart = 0;
int minend = 0;
q.pop_back();
for(int j = 0;j < q.size();j++)
{
int top = q[j];
for(int i = Head[top];i;i = E[i].next)
{
int to = E[i].to;
int cost = E[i].value + dis[top];
if(!vis[to]&&cost< Min)
{
Min = cost;
minstart = q[j];
minend = to;
}
}
q.push_back(minend);
vis[minend] = 1;
}
for(int i = Head[minstart];i;i = E[i].next)
{
int to = E[i].to;
dis[to] = min(dis[to],dis[minstart] + E[Min].value);
}
if(vis[end]) break;
}
}
Dijstra算法基于优先队列的优化
在上面的操作中我们每次需要去找一个目前距离起始点最近的点,对于这个点的查找其实我们可以使用优先队列进行优化
What is the poritory_queue?
优先队列是一种数据结构,里面的每一个元素都有一个优先级,我们可以根据我们的需要使得里面最大的元素和最小的元素进行出队的操作,优先队列的实现通常是基于二叉堆进行操作
知道是怎么实现的即可,在现实使用中当然还是STL大法好呀!!!
priority_queue<data>Q;
// 使用优化队列保证在这个每次去出的开头是距离原点最近的点
void Dijstra(int start)
{
data a = {start,0};
Q.push(a);
while (!Q.empty())
{
data temp = Q.top();
Q.pop();
vis[temp.to] = 1;
for(int i = Head[temp.to];i;i = E[i].next)
{
int to = E[i].to;
if(vis[to]) continue;
data temp1 = {to, dis[temp.to] + E[i].value};
if(temp1.cost < dis[to])
{
dis[to] = temp1.cost;
Q.push(temp1);
}
}
// 更新我们选择的点的可到达点,并且将他们加入到我们的优先队列中去
}
}