1. 程式人生 > 其它 >最短路(dij)

最短路(dij)

最短路(dij)

單標尺

只輸出最短距離(N^2)

要輸出最短路徑(N^2)

只輸出最短距離(mlogN)

多標尺

只輸出最短距離(N^2)

演算法筆記.胡凡(有c的速成).pdf p389

#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<deque>
#include<map>
#include<string>
#include<stack>
#include<cstring>
#include
<set> #include<math.h> #include<algorithm> #define ll long long using namespace std; const int INF = 0x3f3f3f3f; //為了memset()可以用 const double eps = 1e-7; const double pi = acos(-1.0); inline ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; } //gcd(0,a)=a static const int N = 50; static
int n, m, a[N][N], weight[N];//n個城市m條路,a存邊權,weight存點權 static int w[N], num[N], d[N];//w:點權之和,num:路徑數,d:邊權和 //它們對每一個案例都要初始化 static bool v[N] = { false }; void dij(int s) { // 初始化 memset(d, INF, sizeof(d)); memset(w, 0, sizeof(w)); memset(num, 0, sizeof(num)); d[s] = 0; w[s]
= weight[s]; num[s] = 1; for (int i = 0; i < n; ++i) { // 找最小 int u = -1, MIN = INF; for (int j = 0; j < n; ++j) { if (!v[j] && d[j] < MIN) { MIN = d[j]; u = j; } } // 設定已訪問 if (u == -1)return; v[u] = true; // 優化 for (int k = 0; k < n; ++k) { if (a[u][k] != INF && !v[k]) { if (d[u] + a[u][k] < d[k]) {//邊權小,直接選 d[k] = d[u] + a[u][k];//邊權覆蓋 w[k] = w[u] + weight[k];//點權覆蓋 num[k] = num[u];//未增加新路線 }else if(d[u] + a[u][k] == d[k]){//邊權一樣,看點權 if (w[u] + weight[k] > w[k])w[k] = w[u] + weight[k];//點權大的就更新 num[k] += num[u];//增加了新路線 } } } } } signed main() { int s, e; cin >> n >> m >> s >> e; for (int i = 0; i < n; ++i)cin >> weight[i];//讀入點權 memset(a, INF, sizeof(a)); int u, v; for (int i = 0; i < m; ++i) { cin >> u >> v ; cin >> a[u][v]; a[v][u] = a[u][v]; } dij(s); printf("%d %d\n", num[e], w[e]); return 0; }