【SPOJ】Highways(矩阵树定理)

题面

Vjudge
洛谷

题解

矩阵树定理模板题

无向图的矩阵树定理:
对于一条边 (u,v) ,给邻接矩阵上 G[u][v],G[v][u] 加一
对于一条边 (u,v) ,给度数矩阵上 D[u][u],D[v][v] 加一
定义霍尔基夫矩阵 C=DG

将基尔霍夫矩阵去除任意一行和任意一列之后,
得到一个 (n1)(n1) 的行列式 C
求解这个行列式的值,最后的 |det(C)| 就是结果

#include
#include
#include
using namespace std;
#define ll long long
#define RG register
#define MAX 13
inline int read()
{
    RG int x=0,t=1;RG char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    if(ch=='-')t=-1,ch=getchar();
    while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    return x*t;
}
int n,m;
ll a[MAX][MAX];
int main()
{
    int T=read();
    while(T--)
    {
        n=read();m=read();
        memset(a,0,sizeof(a));
        while(m--)
        {
            int u=read(),v=read();
            a[u][u]++;a[v][v]++;
            a[u][v]--;a[v][u]--;
        }
        --n;ll ans=1;
        for(int i=1;i<=n;++i)
        {
            for(int j=i+1;j<=n;++j)
                while(a[j][i])
                {
                    ll t=a[i][i]/a[j][i];
                    for(int k=i;k<=n;++k)a[i][k]-=t*a[j][k],swap(a[i][k],a[j][k]);
                    ans=-ans;
                }
                ans*=a[i][i];
        }
        printf("%lld\n",ans);
    }
    return 0;
}

你可能感兴趣的:(【SPOJ】Highways(矩阵树定理))