BZOJ 4031 HEOI2015 小Z的房间 Matrix-Tree定理

题目大意:给定一张地图,求生成树个数

Matrix-Tree定理直接上

不过模数是109,不能直接求逆元

因此消元的时候辗转相除一下就好了

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 110
#define MOD 1000000000
using namespace std;
const int dx[]={0,0,1,-1};
const int dy[]={1,-1,0,0};
int m,n,tot;
char map[15][15];
int num[15][15];
long long f[M][M];
long long Gauss_Elimination(int n)
{
    int i,j,k,mark=0;
    for(i=1;i<=n;i++)
    {
        for(k=i;k<=n;k++)
            if(f[k][i])
                break;
        if(k==n+1)
            continue;
        if(i!=k)
        {
            mark^=1;
            for(j=i;j<=n;j++)
                swap(f[i][j],f[k][j]);
        }
        for(k=i+1;k<=n;k++)
        {
            while(f[k][i])
            {
                int temp=f[k][i]/f[i][i];
                for(j=i;j<=n;j++)
                    (f[k][j]+=MOD-f[i][j]*temp%MOD)%=MOD;
                if(!f[k][i])
                    break;
                mark^=1;
                for(j=i;j<=n;j++)
                    swap(f[i][j],f[k][j]);
            }
        }
    }
    long long re=1;
    for(i=1;i<=n;i++)
        (re*=f[i][i])%=MOD;
    if(mark)
        re=(MOD-re)%MOD;
    return re;
}
int main()
{
    //freopen("room.in","r",stdin);
    //freopen("room.out","w",stdout);
    int i,j,k;
    cin>>m>>n;
    for(i=1;i<=m;i++)
    {
        scanf("%s",map[i]+1);
        for(j=1;j<=n;j++)
            if(map[i][j]==‘.‘)
                num[i][j]=++tot;
    }
    for(i=1;i<=m;i++)
        for(j=1;j<=n;j++)
            if(num[i][j])
                for(k=0;k<4;k++)
                {
                    int xx=i+dx[k];
                    int yy=j+dy[k];
                    if(!num[xx][yy])
                        continue;
                    f[num[i][j]][num[i][j]]++;
                    f[num[i][j]][num[xx][yy]]--;
                }
    for(i=1;i<=tot;i++)
        for(j=1;j<=tot;j++)
            if(f[i][j]<0)
                f[i][j]+=MOD;
    cout<<Gauss_Elimination(tot-1)<<endl;
    return 0;
}
时间: 2024-12-29 01:09:32

BZOJ 4031 HEOI2015 小Z的房间 Matrix-Tree定理的相关文章

BZOJ 4031 [HEOI2015]小Z的房间(Matrix-Tree定理)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4031 [题目大意] 你突然有了一个大房子,房子里面有一些房间. 事实上,你的房子可以看做是一个包含n*m个格子的格状矩形, 每个格子是一个房间或者是一个柱子.在一开始的时候,相邻的格子之间都有墙隔着. 你想要打通一些相邻房间的墙,使得所有房间能够互相到达. 在此过程中,你不能把房子给打穿,或者打通柱子(以及柱子旁边的墙). 同时,你不希望在房子中有小偷的时候会很难抓, 所以你希望任意

BZOJ 4031: [HEOI2015]小Z的房间

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=4031 矩阵树定理. 基尔霍夫矩阵就是对于i=j,a[i][j]=d[i],对于i!=j,a[i][j]=a[j][i]=-1(如果可以连边的话),否则就是0. 然后把这个矩阵去掉第i行第i列,解这个行列式(删掉第n行比较方便嘛..) 模数比较坑爹,并不是一个质数,所以辗转相除. #include<string> #include<iostream> #include<al

【BZOJ 4031】 4031: [HEOI2015]小Z的房间 (Matrix-Tree Theorem)

4031: [HEOI2015]小Z的房间 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1089  Solved: 533 Description 你突然有了一个大房子,房子里面有一些房间.事实上,你的房子可以看做是一个包含n*m个格子的格状矩形,每个格子是一个房间或者是一个柱子.在一开始的时候,相邻的格子之间都有墙隔着. 你想要打通一些相邻房间的墙,使得所有房间能够互相到达.在此过程中,你不能把房子给打穿,或者打通柱子(以及柱子旁边的墙).同

【BZOJ4031】[HEOI2015]小Z的房间 矩阵树定理

[BZOJ4031][HEOI2015]小Z的房间 Description 你突然有了一个大房子,房子里面有一些房间.事实上,你的房子可以看做是一个包含n*m个格子的格状矩形,每个格子是一个房间或者是一个柱子.在一开始的时候,相邻的格子之间都有墙隔着. 你想要打通一些相邻房间的墙,使得所有房间能够互相到达.在此过程中,你不能把房子给打穿,或者打通柱子(以及柱子旁边的墙).同时,你不希望在房子中有小偷的时候会很难抓,所以你希望任意两个房间之间都只有一条通路.现在,你希望统计一共有多少种可行的方案.

bzoj4031 [HEOI2015]小Z的房间——矩阵树定理

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4031 矩阵树定理的模板题(第一次的矩阵树定理~): 有点细节,放在注释里了. 代码如下: #include<iostream> #include<cstdio> #include<cstring> using namespace std; typedef long long ll; int const mod=1e9; int n,m,a[105][105],d[

[HEOI2015] 小Z的房间 - 矩阵树定理

#include <bits/stdc++.h> using namespace std; #define int long long const int N = 105; const int mod = 1e+9; namespace mat { int a[N][N]; int n,p=1; int Gauss() { int ans = 1; for(int i = 1; i < n; i ++) { for(int j = i + 1; j < n; j ++) while

【bzoj4031】[HEOI2015]小Z的房间 &amp;&amp; 【bzoj4894】天赋 (矩阵树定理)

来两道矩阵树模板: T1:[bzoj4031][HEOI2015]小Z的房间 Description 你突然有了一个大房子,房子里面有一些房间.事实上,你的房子可以看做是一个包含n*m个格子的格状矩形,每个格子是一个房间或者是一个柱子.在一开始的时候,相邻的格子之间都有墙隔着.你想要打通一些相邻房间的墙,使得所有房间能够互相到达.在此过程中,你不能把房子给打穿,或者打通柱子(以及柱子旁边的墙).同时,你不希望在房子中有小偷的时候会很难抓,所以你希望任意两个房间之间都只有一条通路.现在,你希望统计

P4111 [HEOI2015]小Z的房间 生成树计数

这个题是生成树计数的裸题,中间构造基尔霍夫矩阵,然后构成行列式,再用高斯消元就行了.这里高斯消元有一些区别,交换两行行列式的值变号,且消元只能将一行的数 * k 之后加到别的行上. 剩下就没啥了... 找到一个写的特别详细的. il int det() { int ans = 1; for (ri i = 1; i <= sz; ++i) { // 当前在消第i个(i,i) for (ri j = i + 1, t; j <= sz; ++j) { // 把它下面对应的位置消成0 while

Bzoj4031 [HEOI2015]小Z的房间

Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1041  Solved: 504 Description 你突然有了一个大房子,房子里面有一些房间.事实上,你的房子可以看做是一个包含n*m个格子的格状矩形,每个格子是一个房间或者是一个柱子.在一开始的时候,相邻的格子之间都有墙隔着. 你想要打通一些相邻房间的墙,使得所有房间能够互相到达.在此过程中,你不能把房子给打穿,或者打通柱子(以及柱子旁边的墙).同时,你不希望在房子中有小偷的时候会很难抓,所