编程语言
首页 > 编程语言> > 2021 年百度之星·程序设计大赛 - 初赛一

2021 年百度之星·程序设计大赛 - 初赛一

作者:互联网

文章目录

1001

边权为0:
f [ u ] [ k ] [ 0 ] = f [ v ] [ k − 1 ] [ 0 ] / d u [ v ] f[u][k][0]=f[v][k-1][0]/du[v] f[u][k][0]=f[v][k−1][0]/du[v]
f [ u ] [ k ] [ 1 ] = f [ v ] [ k − 1 ] [ 1 ] / d u [ v ] f[u][k][1]=f[v][k-1][1]/du[v] f[u][k][1]=f[v][k−1][1]/du[v]
边权为1:
f [ u ] [ k ] [ 0 ] = f [ v ] [ k − 1 ] [ 1 ] / d u [ v ] f[u][k][0]=f[v][k-1][1]/du[v] f[u][k][0]=f[v][k−1][1]/du[v]
f [ u ] [ k ] [ 1 ] = f [ v ] [ k − 1 ] [ 0 ] / d u [ v ] f[u][k][1]=f[v][k-1][0]/du[v] f[u][k][1]=f[v][k−1][0]/du[v]
这个转移可以矩阵优化
[u][0]和[u][1]看作两个点
1x2n的k-1条边矩阵和2n*2n的转移矩阵相乘得到k条边的1X2n的矩阵。
但是比赛结束放到hdu上,评测机好像不咋给力。
貌似是有更优的优化,不管啦。复杂度 O ( N 3 l o g k ) O(N^3logk) O(N3logk)这个N是200

#include <bits/stdc++.h>
using namespace std;
const int mod=998244353;
char buf[1000001],*p1=buf,*p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++)
inline int read() {
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
int n,m,k,ru[122],a[122][122];
int q_pow(int a,int b) {
    int ans=1;
    while(b) {
        if(b&1) ans=1LL*ans*a%mod;
        a=1LL*a*a%mod,b>>=1;
    }
    return ans;
}
struct Matrix {
    int m[222][222];
    Matrix operator * (const Matrix &b) const {
        Matrix c={0};
        for(int i=1;i<=2*n;++i) {
            for(int k=1;k<=2*n;++k) {
                if(!m[i][k]) continue;
                for(int j=1;j<=2*n;++j)
                    c.m[i][j]=(c.m[i][j]+1LL*m[i][k]*b.m[k][j]%mod)%mod;
            }
        }
        return c;
    }
};
Matrix my_pow(Matrix a,int b) {
    Matrix ans={0};
    for(int i=1;i<=n;++i) ans.m[i][i]=1;
    while(b) {
        if(b&1) ans=ans*a;
        a=a*a,b>>=1;
    }
    return ans;
}
int main() {
    int T=read();
    while(T-->0) {
        n=read(),m=read(),k=read();
        for(int i=1;i<=n;++i) {
            ru[i]=0;
            for(int j=1;j<=n;++j) a[i][j]=0;
        }
        for(int i=1;i<=m;++i) {
            int u=read(),v=read();
            a[u][v]=a[v][u]=read()+1;
            ru[u]++,ru[v]++;
        }
        for(int i=1;i<=n;++i) ru[i]=q_pow(ru[i],mod-2);
        Matrix dsr={0};
        for(int i=1;i<=n;++i) {
            for(int j=1;j<=n;++j) {
                if(a[i][j]) {
                    dsr.m[j+(a[i][j]-1)*n][i]=ru[j];
                    dsr.m[j+n-(a[i][j]-1)*n][i+n]=ru[j];
                }
            }
        }
        dsr=my_pow(dsr,k);
        printf("%d\n",dsr.m[1][n+n]);
    }
    return 0;
}

标签:ru,Matrix,int,初赛,read,2021,ans,du,之星
来源: https://blog.csdn.net/weixin_45564571/article/details/119415860