单源最短路径
Floyd
O(N3)
int Floyd(int start, int end){
memset(dis, Inf, sizeof(dis));
for(int k = 1; k <= N; k++){
for(int i = 1; i <= N; i++){
for(int j = 1; j <= N; j++){
dis[i][j] = min(dis[i][j], dis[i][k]+dis[k][j]);
}
}
}
return dis[start][end];
}
Dijkstra(heap)
O(M+NlgN)
int Dijkstra(int start, int end){
memset(dis, Inf, sizeof(dis));
memset(vis, 0, sizeof(vis));
typedef pair<int, int> Pair;
priority_queue< Pair, vector<Pair>, greater<Pair> > que;
que.push(make_pair((dis[start]=0), start));
while(!que.empty()){
Pair cnt = que.top();
que.pop();
int now = cnt.second;
if(vis[now]) continue;
vis[now] = 1;
int t = st[now];
while(t != 0){
if(dis[H[t].v] > dis[now]+H[t].w){
dis[H[t].v] = dis[now] + H[t].w;
if(!vis[H[t].v]) que.push(make_pair(dis[H[t].v], H[t].v));
}
t = H[t].next;
}
}
return dis[end];
}
Spfa
O(MN)
int Spfa(int start, int end){
memset(dis, Inf, sizeof(dis));
memset(vis, 0, sizeof(vis));
queue<int> que;
que.push(start);
vis[start] = 1;
dis[start] = 0;
while(!que.empty()){
int now = que.front();
que.pop();
int t = st[now];
vis[now] = 0;
while(t != 0){
if(dis[H[t].v] > dis[now]+H[t].w){
dis[H[t].v] = dis[now] + H[t].w;
if(!vis[H[t].v]) que.push(H[t].v);
vis[H[t].v] = 1;
}
t = H[t].next;
}
}
return dis[end];
}
注意:
memset(,,sizeof())
记得写头文件 #include<cstring>
从网上抠下来一张表:
稠密图 | 稀疏图 | 有负权边 | |
---|---|---|---|
单源问题 | Dijkstra+heap | SPFA (或Dijkstra+heap,根据稀疏程度) | SPFA |
APSP(无向图) | SPFA(优化)/Floyd | SPFA(优化) | SPFA(优化) |
APSP(有向图) | Floyd | SPFA (或Dijkstra+heap,根据稀疏程度) | SPFA |
但是某次考试 单源 稠密图 Dijkstra+heap 迷之比 Spfa 慢 3~4倍……