【POJ3613】牛のリレー

トピックリンク:https://www.acwing.com/problem/content/347/

タイトル効果:無向重み付きグラフを考えると、から見つけるために\(S \)\(E \)直後(N- \)\エッジの最短経路

解決

見つけるのは困難ではない、頂点の数が多くなるかもしれないが、ないよりそう離散ノード番号べき最初の一見のため、辺の数100より

行列\(G ^ R&LT \)を表し、直後\(R&LT \)最短エッジ、前記\(G ^ R [I] [J]は、\) を表し\(I \)\(Jを\ )直後\(R&LT \)最短パスエッジは、明らかに次の推論を引き出すことができる:
\ [G ^ R&LT [I] [J] = MIN_ {K \} n型のLeq \左\ {G ^ P [I] [K] + G ^ Q [ k]は[J] \右\}(R = P + Q、nはノードの数である)\]
この式は連想であることを見出し、迅速マトリックスによって決定することができる迅速に電源\(G ^ R&LT \) \(^ N-G [S] [E] \)要求の対象であります

コード

#include<bits/stdc++.h>
using namespace std;
template <typename T> inline void read(T &FF) {
    int RR = 1; FF = 0; char CH = getchar();
    for(; !isdigit(CH); CH = getchar()) if(CH == '-') RR = -RR;
    for(; isdigit(CH); CH = getchar()) FF = FF * 10 + CH - 48;
    FF *= RR;
}
inline void file(string str) {
    freopen((str + ".in").c_str(), "r", stdin);
    freopen((str + ".out").c_str(), "w", stdout);
}
const int N = 205;
int n, m, s, e, path[N][3], ni, num[N];
struct matrix{
    int g[N][N];
    matrix() {
        memset(g, 0x3f, sizeof(g));
        //for(int i = 1; i <= n; i++) g[i][i] = 0;
    }
    friend matrix operator * (const matrix &ai, const matrix &bi) {
        matrix res;
        for(int k = 1; k <= ni; k++)
            for(int i = 1; i <= ni; i++)
                for(int j = 1; j <= ni; j++)
                    res.g[i][j] = min(res.g[i][j], ai.g[i][k] + bi.g[k][j]);
        return res;
    }
}base;
void cpy(matrix &ai, const matrix &bi) {
    for(int i = 1; i <= ni; i++)
        for(int j = 1; j <= ni; j++)
            ai.g[i][j] = bi.g[i][j];
}
matrix Qpow(int ki) {
    if(ki == 1) return base;
    matrix hi = Qpow(ki / 2); cpy(hi, hi * hi);
    return ki & 1 ? hi * base : hi;
}
int main() {
    //file("");
    read(n), read(m), read(s), read(e);
    for(int i = 1; i <= m; i++) {
        read(path[i][0]), read(path[i][1]), read(path[i][2]);
        num[++ni] = path[i][1], num[++ni] = path[i][2];
    }
    sort(num + 1, num + ni + 1);
    ni = unique(num + 1, num + ni + 1) - num - 1;
    //for(int i = 1; i <= n; i++) base.g[i][i] = 0;
    for(int i = 1; i <= m; i++) {
        path[i][1] = lower_bound(num + 1, num + ni + 1, path[i][1]) - num;
        path[i][2] = lower_bound(num + 1, num + ni + 1, path[i][2]) - num;
        base.g[path[i][1]][path[i][2]] = base.g[path[i][2]][path[i][1]] = path[i][0];
    }
    s = lower_bound(num + 1, num + ni + 1, s) - num;
    e = lower_bound(num + 1, num + ni + 1, e) - num;
    matrix ans = Qpow(n);
    cout << ans.g[s][e] << endl;
    return 0;
}

おすすめ

転載: www.cnblogs.com/magicduck/p/12241818.html