Dijkstra用于计算某一结点到其他所有节点的最短路
适用于边权为正的有向图或者无向图
将图中点分为两部分,一部分是已经求出最短路的点S,一部分是未求出最短路的点U,开始时S={0}, U={剩下的点}, 用d[i]表示点i到点0的距离,从U中找到d[i]最小的点m, 加入S中, 更新U中与m相连的点的d[i](松弛操作),直到图中所有的点都加入S中。
memset(vis, 0 sizeof(vis));//vis数组标记点是否被访问过
memset(d, 0x3f, sizeof(d));
d[0] = 0;
for(int i=0; i<n; i++)
{
int x, m = INF;
for(int j=0; j<n; i++)
{
if(!v[j] && d[j]<=m)
m = d[x=j];//找到U中离0最近的边
}
v[x] = 1;
for(int j=0; j<n; j++)
{
d[j] = min(d[j], d[x] + w[x][j]);
}//松弛
}
算法时间复杂度O(n^2)
O(m*logn)算法:优先队列实现
紫书刘汝佳模板:
struct Edge
{
int from, to, dist;
Edge (int u, int v, int d):from(u), to(v), dist(d){}
};
struct HeapNote
{
int d, u;
bool operator < (const HeapNote& rhs)const
{
return d > rhs.d;
}
};
struct Dijkstra
{
int n, m;
vector<Edge>edges;
vector<int>G[maxn];
bool done[maxn];
int d[maxn];
int p[maxn];
void init(int n)
{
this->n = n;
for(int i=0; i<n; i++)
G[i].clear();
edges.clear();
}
void AddEdge(int from, int to, int dist)
{
edges.push_back(Edge(from, to, dist));
m = edges.size();
G[from].push_back(m-1);
}
void dijkstra(int s)
{
priority_queue<HeapNote>Q;
for(int i=0; i<n; i++)
d[i] = INF;
d[s] = 0 ;
memset(done, 0, sizeof(done));
Q.push((HeapNote){0, s});
while(!Q.empty())
{
HeapNote x = Q.top();
Q.pop();
int u = x.u;
if(done[u]) continue;
done[u] = true;
for(int i=0; i<G[u].size(); i++)
{
Edge& e = edges[G[u][i]];
if((d[e.to] > d[u] + e.dist))
{
d[e.to] = d[u] + e.dist;
p[e.to] = G[u][i];
Q.push((HeapNote){d[e.to], e.to});
}
}
}
}
};