单源最短路径算法模板(Dijkstra+BellmanFrod)
2013-08-22 21:58
651 查看
//最短路径算法模板 //前面两个结构体共用 #include<queue> #include<vector> #include<cstring> #define maxn 99 //按最大节点数宏定义 #define INF 0xfffffff using namespace std; struct Edge //节点结构体 { int from; //起始点 int to; //终止点 int dist; //起始点到终止点的距离 }; struct HeapNode //队列节点结构体,用于入队 { int d; //该点到汇点的距离 int u; //该点 bool operator <(const HeapNode& rhs) const { return d>rhs.d; //优先队列,距离优先,距离值小的点在队头 } }; /*Dijkstra算法求最短路径 时间复杂度:O(ElogE) 步骤: 1、初始化距离数组 2、设置所有点为未访问过 3、找出所有未访问过得点中距离最小的点,标记其为访问过 4、对操作(3)中所找到的点的相邻的边进行松弛 5、重复操作(3)和(4)直到所有点都访问过 */ /*算法特点: 用于计算边权均为正的图的单源最短路径,若存在权为负的节点,则无法求解 */ struct Dijkstra { int n,m; vector<Edge> edges; //点数和边数 vector<int> G[maxn]; //边列表,i边可连通到边G[i][j]; bool done[maxn]; //是否已永久标记 int d[maxn]; //s汇点到各点的距离 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> Q; for(int i=0;i<n;i++)d[i]=INF;//所有点到汇点的距离初始化为最大值 d[s]=0; //自身到自身的距离为0; memset(done,0,sizeof(done)); //未处理任何定点,所有标记初始化为0 Q.push((HeapNode){0,s}); while(!Q.empty()) { HeapNode x=Q.top(); Q.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]; Q.push((HeapNode){d[e.to],e.to}); } } } } }; /*BellmanFrod算法求最短路径 时间复杂度:O(kE) 步骤: 1、初始化d数组,ds=0,di=INF 2、枚举每一条边,进行松弛操作 3、将操作(2)重复执行|v|-1次 4、枚举每一条边,看是否还能进行松弛操作,若能,说明原图存在负权环 */ /*算法特点: 可用于计算存在权为负的边的图中的单源最短路径(当最短路径存在时) */ struct BellmanFrod { int n; int m; vector<Edge> edges; vector<int>G[maxn]; bool inp[maxn];//点是否在队列中 double d[maxn];//s到各点的距离 int p[maxn]; //最短路上的一条弧 int cnt[maxn]; //进队次数 //如果某节点进队n次,可以判断存在负圈 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,double dist) { edges.push_back((Edge){from,to,dist}); m=edges.size(); G[from].push_back(m-1); } bool negtiveCycle() { queue<int> Q; memset(inp,0,sizeof(inp)); memset(cnt,0,sizeof(cnt)); for(int i=0;i<n;i++) { d[i]=0; inp[0]=true; Q.push(i); } while(!Q.empty()) { int u=Q.front(); Q.pop(); inp[u]=false; 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]; if(!inp[e.to]) { Q.push(e.to); inp[e.to]=true; if(++cnt[e.to]>n)return true; } } } } return false; } };
相关文章推荐
- 单源最短路径算法模板(Dijkstra+BellmanFrod)
- AOJ GRL_1_B: Shortest Path - Single Source Shortest Path (Negative Edges) (Bellman-Frod算法求负圈和单源最短路径)
- 图论;单源最短路径;拓扑排序+松弛(有向无回路);Bellman-Ford(回路,负权回路)Dijkstra(无负权,可回路);可以用最小堆实现算法的优化;
- (最短路径算法整理)dijkstra、floyd、bellman-ford、spfa算法模板的整理与介绍
- 图论;单源最短路径;拓扑排序+松弛(有向无回路);Bellman-Ford(回路,负权回路);Dijkstra(无负权,可回路);可以用最小堆实现算法的优化;
- (最短路径算法整理)dijkstra、floyd、bellman-ford、spfa算法模板的整理与介绍
- 图论;单源最短路径;拓扑排序+松弛(有向无回路);Bellman-Ford(回路,负权回路);Dijkstra(无负权,可回路);可以用最小堆实现算法的优化;
- 单源最短路径:Dijkstra 算法 Bellman_Ford 算法 SPFA 算法
- 最短路径算法 模板_Dijkstra_Bellman.ford_Floyd_spfa
- 几个最短路径算法Floyd、Dijkstra、Bellman-Ford、SPFA的比较
- Dijkstra算法求单源最短路径
- [模板] Dijkstra单源最短路径
- 初学图论-Dijkstra单源最短路径算法基于优先级队列(Priority Queue)的实现
- Dijkstra单源最短路径算法; 优先队列+静态数组邻接表; STL优先队列还是没想明白排序原则;
- 贪心算法 - 单源最短路径 Dijkstra
- Dijkstra求单源最短路径(图论基础算法)
- Dijkstra算法求单源最短路径
- 几个最短路径算法Floyd、Dijkstra、Bellman-Ford、SPFA的比较
- //九度教程78 dijkstra算法之单源最短路径
- 单源最短路径算法--Dijkstra算法和Bellman-Ford算法