ABC236G 题解

ABC236G 题解

题面

原题传送门(洛谷)

原题传送门(Atcoder)

一言

矩阵并不只是矩阵,很多的转移式只要满足矩阵的形式就可以用矩阵来优化。

思路

注意到 \(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
posted @ 2025-08-03 23:07  naroto2022  阅读(4)  评论(0)    收藏  举报