dijkstra用于解决无负权的带权有向图或无向图的单源最短路径问题,时间复杂度为V^2,用对优化的时间复杂度为E*log(V)(优化常用稀疏图);dijkstra算法常用于一些问题的预处理上;
dijkstra算法是按照最短路距离源点由近及远的顺序逐一求出每个点距离源点的最短路的;用近点去更新,退出远点的距离,局部最优决定整体最优;
具体实现:贪心的思想,设s是源点,如果离s前k-1近的点已经被确定,构成点集P,那么从s到离s第k近的点t的路径{s,p1,p2,p3,......pi,t}满足s,p1,p2,p3......pi属于P;如果有pi不属于P的话,因为边权非负,pi到t的路径非负,则d[pi] <= d[t],pi才是第k近;
(1)、初始化d[i] = i == s ? 0 : INF; P为空集;
(2)、找到最小的d[i](i不属于P);
(3)、把i加入P中,对于任意的j不属于P,更新d[j]的值:d[j] = min(d[j],d[i] + dist[i][j]);
(4)、循环直到所有的点都加入集合P中;
poj3159 dijkstra模板题;
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<cctype>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<set>
#include<string>
#include<stack>
#include<map>
#define ll long long
#define MAX 50010
#define MAXN 150010
#define INF 2000000000
#define eps 1e-8
using namespace std;
struct Edge{
int from,to,dist;
};
struct Node{
int num,w;
bool operator < (const Node& rhs) const{
return rhs.w < w;
}
};
vector<Edge>edges;
int first[MAXN],next[MAXN]; //刚开始用了一个vector<int>G[MAX]建图,发现会超时
int n;
void init(){
memset(first,-1,sizeof(first));
memset(next,-1, sizeof(next));
//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});
int k = edges.size();
next[k-1] = first[from];
first[from] = k-1;
}
int dijkstra(int s){
int d[MAX],vis[MAX];
priority_queue<Node>q;
q.push((Node){s,0});
memset(vis,0,sizeof(vis));
for (int i=0; i<n; i++) d[i] = (i == s ? 0 : INF);
while (!q.empty()){
Node t = q.top();
q.pop();
int u = t.num;
if (vis[u]) continue;
vis[u] = 1;
for (int v=first[u]; v != -1; v = next[v]){
Edge e = edges[v];
if (!vis[e.to]){
d[e.to] = min(d[e.to],d[u] + e.dist);
q.push((Node){e.to,d[e.to]});
}
}
}
return d[n-1];
}
int main(){
int m;
while (scanf("%d%d",&n,&m) != EOF){
int x,y,z;
init();
for (int i=0; i<m; i++){
scanf("%d%d%d",&x,&y,&z);
x--;
y--;
addEdge(x,y,z);
}
printf("%d\n",dijkstra(0));
}
return 0;
}