dijkstra算法处理非负边权有向图的最短路。时间复杂度为O(V^2)
算法原理:
假设与S相连的节点中离S最近的节点为T,并且距离为dist,那么不存在另外的路径使得从S到T的距离小于dist,于是就知道了S到T的最短路。
然后把S和T当做一个节点即为tmp,那么与tmp相连节点中(即与S或T相连的节点中)距离tmp最近的节点设为u,就找到了tmp到u的最短路,也就是S到 u 的最短路。
以此类推,就是维护两个集合,一个是源点集合,,一个是非源点集合,每次都把一个非源点集合中的距离源点集合最近的点加入源点集合。
vector<int>g[N], e[N];
int dis[N];
bool vis[N];
void add(int u, int v, int c){
g[u].push_back(v);
e[u].push_back(c);
}
//O(v^2)
void dijkstra(int s, int n){
memset(dis, 0x3f, sizeof dis);
memset(vis, false, sizeof vis);
dis[s] = 0;
vis[s] = true;
int u = s, tmp = n;
while (tmp--){
for (int i = 0; i < g[u].size(); i++){
int v = g[u][i], c = e[u][i];
dis[v] = min(dis[u] + c, dis[v]);
}
u = -1;
for (int i = 1; i <= n; i++){
if (vis[i] == false && (u == -1 || dis[i] < dis[u]))
u = i;
}
vis[u] = true;
}
}
struct node{
int id, dist;
node(int i, int j) :id(i), dist(j){}
bool operator<(const node&op)const{
return dist>op.dist;
}
};
vector<int>g[N], e[N];
int dis[N];
queue<node>q;
void add(int u, int v, int c){
g[u].push_back(v);
e[u].push_back(c);
}
void dijkstra(int s){
memset(dis, 0x3f, sizeof dis);
int u = s;
dis[u] = 0;
q.push(node(u, 0));
while (!q.empty()){
node now = q.front();
u = now.id; q.pop();
for (int i = 0; i < g[u].size(); i++){
int v = g[u][i], c = e[u][i];
if (dis[v]>dis[u] + c){
dis[v] = dis[u] + c;
q.push(node(v, dis[v]));
}
}
}
}