Dijkstra算法
题目:luogu P4779
分析:实现Dijkstra算法,基于binary heap可以得到$O((m+n)\log{n})$的复杂度,基于Fibonacci heap可以得到$O(m+n\log{n})$的复杂度。这里我们采用优先队列priority_queue. 注意:Dijkstra算法只能求解边权为非负的图。
代码:
#include<iostream> #include<queue> #include<vector> #include<functional> #include<cstdio> #include<string.h> using namespace std; struct { int weight;//边权 int toVer;//边(u,v)对应的v int nex;//边(u,v1)上一条共起点的边(u,v2)的编号 } edge[200005]; int utoe[100005]; int dis[100005]; int vis[100005]; struct node { int distance; int vertex; node(){} node(int x, int y) { distance = x; vertex = y; } }; bool operator>(node a, node b) { return a.distance > b.distance; } int INF = 1e9 + 1; priority_queue< node, vector<node>, greater<node> >q; void Dijkstra(int s) { dis[s] = 0; q.push(node(0, s)); node top_ele; int e_idx; int v_temp; int dis_temp; while (!q.empty()) { top_ele = q.top(); q.pop(); if (vis[top_ele.vertex] == 1) continue; vis[top_ele.vertex] = 1; e_idx = utoe[top_ele.vertex]; while (e_idx>0) { v_temp = edge[e_idx].toVer; if (vis[v_temp] == 0) { dis_temp = top_ele.distance + edge[e_idx].weight; if (dis_temp < dis[v_temp]) { dis[v_temp] = dis_temp; q.push(node(dis_temp, v_temp)); } } e_idx = edge[e_idx].nex; } } } int main() { int n, m, s; int u, v, w; int i; int id_e; while (scanf("%d%d%d", &n, &m, &s) == 3) { id_e = 0; memset(utoe, 0, sizeof(utoe)); for (i = 0; i < m; i++) { scanf("%d%d%d", &u, &v, &w); edge[++id_e].weight = w; edge[id_e].toVer = v; edge[id_e].nex = utoe[u]; utoe[u] = id_e; } for (i = 1; i <= n; i++) dis[i] = INF; memset(vis, 0, sizeof(vis)); Dijkstra(s); for (i = 1; i <= n; i++) printf("%d ", dis[i]); printf("\n"); } return 0; }