图论——Dijkstra算法
本文作者frankchenfu,blogs网址http://www.cnblogs.com/frankchenfu/,转载请保留此文字。
图论其实是比较难的一种题型,但是一些模板题,是没有什么太大难度的!
这里给大家带来的是迪杰斯特拉(Dijkstra)算法。
迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法。
是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题。
迪杰斯特拉算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。
#include<cstdio> #include<cstring> #include<queue> #define reg register using namespace std; const int N=100001; const int M=100001; int n,m,s,t,d[N]; int edge,e[M],b[M],w[M],fir[N]; void add(reg int x,reg int y,reg int z) { e[++edge]=y; w[edge]=z; b[edge]=fir[x]; fir[x]=edge; } struct node { int i,di; }; bool operator<(node a,node b) { return a.di>b.di; } priority_queue<node>que; void input() { scanf("%d%d%d%d",&n,&m,&s,&t); for(reg int i=1;i<=m;i++) { reg int x,y,z; scanf("%d%d%d",&x,&y,&z); add(x,y,z); add(y,x,z); } memset(d,0x7f,sizeof(d)); que.push((node){s,0}); d[s]=0; } void work() { for(;!que.empty();) { node t=que.top(); que.pop(); if(d[t.i]!=t.di) continue; for(reg int k=fir[t.i];k;k=b[k]) if(t.di+w[k]<d[e[k]]) { d[e[k]]=t.di+w[k]; que.push((node){e[k],d[e[k]]}); } } } void output() { printf("%d\n",d[t]); } int main() { input(); work(); output(); return 0; }
我们看到,一般的Dijkstra算法好像不需要STL,可是这个优先队列呢?它是进行堆优化的。
理论上,堆优化可以是Dijkstra算法时间复杂度降到O(n log n),这样不是很好吗?多写几行,时间快不少,何乐而不为?
需要注意的大概就这些,希望大家继续努力,天天AC!
备注:
标准模板题是 [USACO09OCT] Heat Wave 热浪。
链接参考(来自“洛谷”):http://www.luogu.org/problem/show?pid=1339