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;
}
不摆烂了,写题