dijkstra算法复杂度:O(V) V为顶点的数目
//dijkstra算法模板
int cost[MAX_V][MAX_V]; //cost[u][v]表示边e=(u,v)的权值,(不存在时这条边设为INF)
int d[MAX_V]; //顶点s出发的最短距离
bool used[MAX_V]; //已经使用过的图
int V; //定点数
//求从s出发到各个顶点的最短距离
void dijkstra(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[]中的值
d[u] = min(d[u], d[v] + cost[v][u]);
}
}
}
优化后的算法复杂度:O(|E|) E为边的数目
//用优先队列优化dijkstra算法模板
struct edge { //cost代表一个点到to这个点的权值
int to, cost;
};
//pair头文件有utility
typedef pair<int ,int > P; //first为最短距离,second为顶点序号
int V; //顶点数
vector<edge> G[MAX_V]; //G[i]存放的是第i个点到 其他点的序号和权值
int d[MAX_V]; //d[i]存放的是指定节点s到i的最短距离
void dijkstra_pri(int s) {
//通过指定greater<P>参数,堆按照first从小到大的顺序取出值
priority_queue<P, vector<P>, greater<P> > que;
fill(d, d+V, INF); //初始化d
d[s] = 0;
que.push(P(0,s)); //把第一个点权值和序号存入
while(!que.empty()) {
P p = que.top(); que.pop();
int v = p.second;
if(p.first > d[v]) 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));
}
}
}
}
//注意:如果是多组数据记得遍历顶点用G[i].clear();来清空G[v],否则会影响第二组数据