P2886 [USACO07NOV]Cow Relays G 题解(矩阵快速幂 floyd)

题目链接

题目大意

\(s\)\(e\)中,恰好经过\(n\)条边的最短路

题目思路

看到经过\(n\)条边,就要想到矩阵快速幂的思想

然后是最短路,利用floyd的思想,不是普通的floyd的稍微有些变化,但是思想是一样的

每一次floyd相当于多走了一条边

还需要离散化

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#define fi first
#define se second
#define pii pair<int,int>
#define debug cout<<"I AM HERE"<<endl;
using namespace std;
typedef long long ll;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int maxn=200+5,inf=0x3f3f3f3f,mod=998244354;
const double eps=1e-6;
int n,t,s,e;
int hs[1000+5],cnt;
struct matrix{
    ll a[maxn][maxn];
}base,ans;
matrix mul(matrix a,matrix b,int n){
    matrix temp;
    memset(temp.a,0x3f,sizeof(temp.a)); //一定1要清空
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            for(int k=1;k<=n;k++){
                temp.a[j][k]=min(temp.a[j][k],a.a[j][i]+b.a[i][k]);
            }
        }
    }
    return temp;
}
void qpow(ll n,ll b){
    while(b){
        if(b&1){
            ans=mul(ans,base,n);
        }
        base=mul(base,base,n);
        b=b>>1;
    }
}
signed main(){
    memset(base.a,0x3f,sizeof(base.a));
    scanf("%d%d%d%d",&n,&t,&s,&e);
    for(int i=1,u,v,w;i<=t;i++){
        scanf("%d%d%d",&w,&u,&v);
        if(!hs[u]) hs[u]=++cnt;
        if(!hs[v]) hs[v]=++cnt;
        base.a[hs[u]][hs[v]]=base.a[hs[v]][hs[u]]=w;
    }
    ans=base;
    qpow(cnt,n-1);
    printf("%lld\n",ans.a[hs[s]][hs[e]]);
    return 0;
}

posted @ 2022-01-21 09:24  hunxuewangzi  阅读(26)  评论(0编辑  收藏  举报