Dijkstra
非负权值单源最短路,Dijkstra算法,O(mlogm)
从未访问的点中选出一个距离源点最近的点,加入到已访问的点中,直到所有点都被访问过为止。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| class Dijkstra{ private: struct edge{ ll v, w; }; struct node{ ll dis, u; bool operator>(const node &a) const { return dis > a.dis; } }; vector<vector<edge>> G; vector<int> vis; vector<ll> dis; priority_queue<node,vector<node>,greater<node>> Q; ll n=0; void Init(){ while(!Q.empty()) Q.pop(); FORLL(i,1,n){ vis[i]=0; dis[i]=INF; } } public: Dijkstra(ll _n):n(_n),G(_n+1),vis(_n+1,0),dis(_n+1,INF){} void addedge(ll u,ll v,ll w){ G[u].push_back({v,w}); } void solve(ll s){ Init(); dis[s] = 0; Q.push({0, s}); while (!Q.empty()) { ll u = Q.top().u; Q.pop(); if (vis[u]) continue; vis[u] = 1; for (auto e : G[u]) { ll v = e.v, w = e.w; if (dis[v] > dis[u] + w) { dis[v] = dis[u] + w; Q.push({dis[v], v}); } } } } ll getdis(ll t){ return dis[t]; } ll operator[](ll i){ return dis[i]; } };
|
Floyd
适用于任何图,不管有向无向,边权正负,但是最短路必须存在(不能有负环)
复杂度比较高,但是常数小,容易实现
定义f[k][x][y]
为从x到y,只能经过1~k的点的最短路,f[k][x][y] = min(f[k-1][x][y], f[k-1][x][k] + f[k-1][k][y])
f[n][x][y]
即为所求
代码略