P2886 [USACO07NOV]Cow Relays G

传送门

天天刷水题,结果都做不出来


思路

我们定义 \(f_{i,u,v}\) 表示从 \(u\)\(v\) ,恰好经过 \(i\) 条边的最短路

我们可以思考这样的一个转移:

\[f_{i,u,v}=\min\{f_{a,u,k}+f_{b,k,v}\}\ (a+b=i) \]

这个样子是不是像极了两个矩阵,矩阵上 \(a_{i,j}\) 表示 \(i\)\(j\) 走过 \(k\) 条边的最短路,然后将这两个矩阵进行 min乘

其实,我们可以将它看成一条一条边扩展,因此转移也可以这样写:

\[f_{i,u,v}=\min\{f_{i-1, u, k}+f_{1,k,v}\} \]

也就是每次乘上一个“单位矩阵”,这就可以用矩阵快速幂来处理


代码

#include<iostream>
#include<fstream>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#define LL long long
#define FOR(i, x, y) for(int i = (x); i <= (y); i++)
#define ROF(i, x, y) for(int i = (x); i >= (y); i--)
#define PFOR(i, x) for(int i = he[x]; i; i = r[i].nxt)
inline int reads()
{
    int sign = 1, re = 0; char c = getchar();
    while(c < '0' || c > '9'){if(c == '-') sign = -1; c = getchar();}
    while('0' <= c && c <= '9'){re = re * 10 + (c - '0'); c = getchar();}
    return sign * re;
}
int n, t, s, e;
int id[1005], cnt;
struct Matrix
{
    int a[105][105];
    Matrix() {memset(a, 63, sizeof(a));}
    inline int* operator [] (const int b) {return a[b];}
    inline Matrix operator * (Matrix b)
    {
        Matrix re;
        FOR(k, 1, cnt) FOR(i, 1, cnt) FOR(j, 1, cnt)
            re[i][j] = std::min(re[i][j], a[i][k] + b[k][j]);
        return re;
    }
}ans;
inline Matrix qpow(Matrix a, int b)
{
    Matrix re = a; b--;
    while(b)
    {
        if(b & 1) re = re * a;
        a = a * a;
        b >>= 1;
    }
    return re;
}
signed main()
{
#ifndef ONLINE_JUDGE
    freopen("test.in", "r", stdin);
    freopen("test.out", "w", stdout);
#endif
    n = reads(), t = reads(), s = reads(), e = reads();
    id[s] = ++cnt, id[e] = ++cnt;
    FOR(i, 1, t)
    {
        int w = reads(), u = reads(), v = reads();
        if(!id[u]) id[u] = ++cnt;
        if(!id[v]) id[v] = ++cnt;
        ans[id[u]][id[v]] = ans[id[v]][id[u]] = std::min(ans[id[u]][id[v]], w);
    }
    ans = qpow(ans, n);
    printf("%d", ans[id[s]][id[e]]);
    return 0;
}
posted @ 2022-08-15 09:32  zuytong  阅读(17)  评论(0编辑  收藏  举报