简单矩阵乘法
可以矩阵套矩阵,也可以只建一个矩阵
std写得是矩阵套矩阵的写法
第一个矩阵(最大的矩阵)
矩阵大小:
矩阵意义:对于代表从i走到j需要的最少体力
矩阵嵌套:对于是一个小矩阵,小矩阵定义参见下方
第二个矩阵(小矩阵)
矩阵大小:
矩阵意义:对于代表走过新路的第i条到第j条的最少体力
矩阵转移
见代码
std
#include<bits/stdc++.h> using namespace std; long long n,m,k,a,b; struct ppp { long long f[12][12]; ppp operator*(const ppp x) { ppp y; memset(y.f,10,sizeof(y.f)); for(long long i=0; i<=b; i++) for(long long j=i; j<=b; j++) for(long long k=i; k<=j; k++) y.f[i][j]=min(y.f[i][j],f[i][k]+x.f[k][j]); return y; } }; ppp Min(ppp x,ppp y) { for(long long i=0; i<=b; i++) for(long long j=0; j<=b; j++) x.f[i][j]=std::min(x.f[i][j],y.f[i][j]); return x; } struct oppo { ppp f[30][30]; oppo operator*(const oppo x) { oppo y; memset(y.f,10,sizeof(y.f)); for(long long k=1; k<=n; k++) for(long long i=1; i<=n; i++) for(long long j=1; j<=n; j++) y.f[i][j]=Min(f[i][k]*x.f[k][j],y.f[i][j]); return y; } } cs,ans; void ksm(long long g) { memset(ans.f,10,sizeof(ans.f)); for(long long i=1; i<=n; i++) ans.f[i][i].f[0][0]=0; while(g) { if(g&1) ans=ans*cs; g>>=1; cs=cs*cs; } long long st=LONG_LONG_MAX; for(long long j=1; j<=n; j++) st=min(st,ans.f[1][j].f[0][b]); if(st!=ans.f[0][0].f[0][0]) cout<<st<<"\n"; else puts("-1"); } int main() { cin>>n>>m>>k>>a>>b; memset(cs.f,10,sizeof(cs.f)); for(long long i=1; i<=m; i++) { long long s,t,u; scanf("%lld%lld%lld",&s,&t,&u); for(long long j=0; j<=b; j++) cs.f[s][t].f[j][j]=u; } for(long long i=1; i<=a; i++) { long long s,t,u; scanf("%lld%lld",&s,&t); for(long long j=1; j<=b; j++) { scanf("%lld",&u); cs.f[s][t].f[j-1][j]=u; } } ksm(k+b); return 0; }