ABC236G 题解
ABC236G 题解
题面
一言
矩阵并不只是矩阵,很多的转移式只要满足矩阵的形式就可以用矩阵来优化。
思路
注意到 \(n\) 很小,\(l\) 很大,看起来就很矩阵。
首先就把边的时刻设为边权。
具体的,设 \(f_{x,i,j}\) 为从 \(i\) 到 \(j\) 走了 \(x\) 步的最小时刻。
则 \(f_1\) 就是题目给的邻接矩阵。
于是就有转移式 \(\boxed{f_{x,i,j}=\min(\max(f_{x-1,i,k},f_{1,k,j}))(i,j,k\in[1,n])}\)。
于是,把 \(j,k\) 两维看成一个广义矩阵,式子就变成 \(f_{x}=f_{x-1}\times{f_1}=f_1^x\),直接矩阵快速幂即可。
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
//#define gc getchar
#define gc()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
#define ll long long
using namespace std;
const int MN=105;
ll n,m,t;
char buf[1<<23],*p1=buf,*p2=buf;
void write(ll n){if(n<0){putchar('-');write(-n);return;}if(n>9)write(n/10);putchar(n%10+'0');}
ll read(){ll x=0,f=1;char ch=gc();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=gc();}return x*f;}
struct matrix{
ll g[MN][MN],d;
matrix(ll x){d=x;for(int i=0; i<d; i++) for(int j=0; j<d; j++) g[i][j]=1e18;}
void init(){for(int i=0; i<d; i++) g[i][i]=0;}
matrix operator * (const matrix a){matrix c(n);for(int i=0; i<d; i++) for(int j=0; j<d; j++) for(int k=0; k<d; k++) c.g[i][j]=min(c.g[i][j],max(g[i][k],a.g[k][j]));return c;}
matrix operator ^ (ll &x){matrix a=*this,res(n);res.init();ll b=x;while(b){if(b&1)res=res*a;a=a*a;b>>=1;}return res;}
};
int main(){
//ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
n=read();m=read();t=read();matrix f(n);
for(int i=1; i<=m; i++){
ll u=read(),v=read();
f.g[u-1][v-1]=i;
}
f=f^t;
for(int i=0; i<n; i++) write(f.g[0][i]==1e18?-1:f.g[0][i]),putchar(' ');putchar('\n');
return 0;
}//250803