【Luogu】P2886牛继电器(矩阵加速floyd)

  题目链接

  矩阵加速floyd……牛逼牛逼。

  注意离散化,注意更新的时候要用旧的权值矩阵更新。

  

#include<cstdio>
#include<cstring>
#include<cctype>
#include<cstdlib>
#include<algorithm>
#define maxn 300
#define check(x) if(x==0)    x=++size;
using namespace std;

inline long long read(){
    long long num=0,f=1;
    char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-')    f=-1;
        ch=getchar();
    }
    while(isdigit(ch)){
        num=num*10+ch-'0';
        ch=getchar();
    }
    return num*f;
}

int size,n;

struct Matrix{
    long long s[maxn][maxn];
    void clear(){memset(s,127/3,sizeof(s));}
    Matrix operator *(const Matrix x){
        Matrix ans;
        for(int k=1;k<=size;++k)
            for(int i=1;i<=size;++i)
                for(int j=1;j<=size;++j)    ans.s[i][j]=min(ans.s[i][j],s[i][k]+x.s[k][j]);
        return ans;
    }
};

Matrix Pow(Matrix now,int x){
    Matrix ret;    memset(ret.s,0,sizeof(ret.s));
    for(int i=1;i<=size;++i)    ret.s[i][i]=1;
    while(x){
        if(x&1)    ret=ret*now;
        now=now*now;
        x>>=1;
    }
    return ret;
}

int id[maxn*4];

int main(){
    int m=read(),e=read(),Start=read(),End=read();
    Matrix ret;ret.clear();
    for(int i=1;i<=n;++i){
        int len=read(),x=read(),y=read();
        check(id[x]);    check(id[y]);
        ret.s[id[x]][id[y]]=len;
    }
    ret=Pow(ret,m);
    printf("%d",ret.s[id[Start]][id[End]]);
    return 0;
}
原文地址:https://www.cnblogs.com/cellular-automaton/p/8367668.html