模板
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
const int maxn=11111;
const int maxm=11111;
const int INF=1e9;
struct Edge{
int from,to,dist;
};
struct HeapNode{
int d,u;
bool operator<(const HeapNode& 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<HeapNode>que;
for (int i=0;i<n;i++) d[i]=INF;
d[s]=0;
memset(done,0,sizeof(done));
que.push((HeapNode){0,s});
while (!que.empty()){
HeapNode x=que.top();
que.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];//p[e.to]=e.from;
que.push((HeapNode){d[e.to],e.to});
}
}
}
}
};
性质
路径统计
用dijkstra还可以枚举两点间的所有最短路,以及统计最短路的条数。枚举最短路的方法是这样的:先求出所有点到目标点的最短路长度d[i],然后从起点开始出发行走,但只沿着d[i]=d[j]+w(i,j)的边走。不难证明,如果一直顺着这样的边走,走到目标点时,走出的一定是最短路;反过来,只要有一次走的不是这样的边,走到目标点时,走出的一定不是最短路。有了这样的结论,计数也不是难事,令f[i]表示从i到目标点的最短路的条数,则f[i]=sum{ f[j] | f[i]=d[j]+w(i,j) },边界条件为终点的f值等于1。
最短路树
用dijkstra算法可以求出单源最短路树,方法是在发现d[i]+w(i,j)<d[j]时除了更新d[j]之外还要设置p[i]=j。这样,把p看成是父指针,则所有点形成了一棵树。这样,要从起点出发沿最短路走到任意其他点,只需要顺着树上的边走即可。前面的dijkstra算法的代码已经求出了p数组。