POJ 3613 Floyd + 矩阵快速幂

159 篇文章 1 订阅
题意

传送门 POJ 3613 Cow Relays

题解

设从 u u u 出发,到 v v v 的长度为 k k k 的最短路径为 G k [ u ] [ v ] G_k[u][v] Gk[u][v],修改 F l o y d Floyd Floyd 算法,则有
G k 1 + k 2 [ u ] [ v ] = min ⁡ 1 ≤ w ≤ V ( G k 1 [ u ] [ w ] + G k 2 [ w ] [ v ] ) G_{k_1+k_2}[u][v]=\min\limits_{1\leq w\leq V}(G_{k_1}[u][w]+G_{k_2}[w][v]) Gk1+k2[u][v]=1wVmin(Gk1[u][w]+Gk2[w][v]) 用矩阵快速幂求解。初始化矩阵时, G 1 G_1 G1 为原图的邻接矩阵,需要注意的是,按照定义,无自环的情况下 G 1 [ u ] [ u ] = i n f G_1[u][u]=inf G1[u][u]=inf;同理 G 0 [ u ] [ u ] = 0 G_0[u][u]=0 G0[u][u]=0。复杂度 O ( T 3 log ⁡ N ) O(T^3\log N) O(T3logN)

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
#define maxt 105
#define maxv 1005
#define inf 0x3f3f3f3f
typedef vector<int> vec;
typedef vector<vec> mat;
int N, T, S, E, A[maxt], B[maxt], L[maxt], nv, cp[maxv];

mat mul(mat &C, mat &D)
{
    mat R(C.size(), vec(D[0].size(), inf));
    for (int i = 0; i < C.size(); ++i)
        for (int k = 0; k < D.size(); ++k)
            for (int j = 0; j < D[0].size(); ++j)
                R[i][j] = min(R[i][j], C[i][k] + D[k][j]);
    return R;
}

mat pow(mat &M, int n)
{
    mat R(M.size(), vec(M.size(), inf));
    for (int i = 0; i < M.size(); ++i)
        R[i][i] = 0;
    while (n)
    {
        if (n & 1)
            R = mul(R, M);
        M = mul(M, M);
        n >>= 1;
    }
    return R;
}

int main()
{
    scanf("%d%d%d%d", &N, &T, &S, &E);
    memset(cp, -1, sizeof(cp));
    for (int i = 0; i < T; ++i)
    {
        scanf("%d%d%d", L + i, A + i, B + i);
        cp[A[i]] = cp[A[i]] != -1 ? cp[A[i]] : nv++;
        cp[B[i]] = cp[B[i]] != -1 ? cp[B[i]] : nv++;
    }
    mat M(nv, vec(nv, inf));
    for (int i = 0; i < T; ++i)
    {
        int x = cp[A[i]], y = cp[B[i]];
        M[x][y] = M[y][x] = L[i];
    }
    M = pow(M, N);
    printf("%d\n", M[cp[S]][cp[E]]);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值