MnZn 求助矩阵树定理
查看原帖
MnZn 求助矩阵树定理
420129
Nt_Tsumiki楼主2024/9/20 07:21

关于本题有向边的情况需要制定 1 为根,对应的也就是把第一行第一列删掉。

但是我这里直接删的第 nn 行和第 nn 列,为啥算出来也是对的。

#include <iostream>
#include <cstdio>

#define N 305
#define MOD 1000000007
#define LL long long

using namespace std;
int n,m,t,d[N];

LL quickpow(LL a,int k) {
    LL res=1;
    while (k) {
        if (k&1) res=res*a%MOD;
        a=a*a%MOD,k>>=1;
    }
    return res;
}

LL a[N][N];

LL det(int n) {
    LL res=1;
    for (int i=1;i<=n;i++) {
        int k=i;
        for (int j=i;j<=n;j++)
            if (a[j][i]) { k=j; break; }
        if (k!=i) swap(a[k],a[i]),res*=-1;
        for (int j=i+1;j<=n;j++) {
            LL tmp=a[j][i]*quickpow(a[i][i],MOD-2)%MOD;
            for (int k=i;k<=n;k++) a[j][k]=((a[j][k]-tmp*a[i][k]%MOD)%MOD+MOD)%MOD;
        }
    }
    for (int i=1;i<=n;i++) res=res*a[i][i]%MOD;
    return res;
}

int main() {
    scanf("%d%d%d",&n,&m,&t); t^=1;
    for (int i=1,u,v,w;i<=m;i++) {
        scanf("%d%d%d",&u,&v,&w); --u,--v;
        (a[u][v]+=MOD-w)%=MOD,(a[v][u]+=MOD-w*t)%=MOD;
        (a[u][u]+=w*t)%=MOD,(a[v][v]+=w)%=MOD;
    }
    LL ans=det(n-1);
    printf("%lld\n",(ans+MOD)%MOD);
    return 0;
}
2024/9/20 07:21
加载中...