最短路(dij)
阿新 • • 發佈:2022-02-13
最短路(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; staticint 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; }