BZOJ 4031: [HEOI2015]小Z的房间
2015-05-03 14:08
274 查看
题目大意:求生成树个数
做法:用matrix-tree定理。对于一个图,求出它的拉普拉斯算子c
c[i][j]=d[i][j]-a[i][j],d为度数矩阵,当i=j时为i的度数,否则为0,a为邻接矩阵。然后求出矩阵c的行列式。我的做法是高斯消元,把c消成一个上三角后求对角线的乘积,但由于这道题要对10^9进行取模,所以消元时不能开double除,而要不断地辗转相除(乘逆元也不行,不是质数)。
Tips:行列式计算时每交换一行乘一个-1,开一个数组记录。
做法:用matrix-tree定理。对于一个图,求出它的拉普拉斯算子c
c[i][j]=d[i][j]-a[i][j],d为度数矩阵,当i=j时为i的度数,否则为0,a为邻接矩阵。然后求出矩阵c的行列式。我的做法是高斯消元,把c消成一个上三角后求对角线的乘积,但由于这道题要对10^9进行取模,所以消元时不能开double除,而要不断地辗转相除(乘逆元也不行,不是质数)。
Tips:行列式计算时每交换一行乘一个-1,开一个数组记录。
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> using namespace std; const int maxn=100+10; const int md=1000000000; int a[maxn][maxn],d[maxn][maxn],map[maxn][maxn],n,id[maxn][maxn],tot,m; long long c[maxn][maxn]; int dx[]={-1,1,0,0}; int dy[]={0,0,-1,1}; char ch[12]; void gauss(int n) { for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) c[i][j]=(c[i][j]+md)%md; int f=1; for(int i=1;i<=n;i++) { int j=i; while(!c[j][i]&&j<=n) j++; if(j==n+1) { puts("0"); return; } if(j!=i) { for(int k=1;k<=n;k++) swap(c[i][k],c[j][k]); f*=-1; } for(int k=i+1;k<=n;k++) { while(c[k][i]) { long long t=c[k][i]/c[i][i]; for(int l=i;l<=n;l++) c[k][l]=(c[k][l]-c[i][l]*t%md+md)%md; if(!c[k][i]) break; for(int l=i;l<=n;l++) swap(c[k][l],c[i][l]); f*=-1; } } } long long res=1; for(int i=1;i<=n;i++) res=(res*c[i][i])%md; if(f<0) res=(md-res)%md; printf("%lld\n",res); } int main() { //freopen("4031.in","r",stdin); //freopen("4031.out","w",stdout); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%s",&ch); for(int j=0;j<m;j++) if(ch[j]=='.') map[i][j+1]=1; else map[i][j+1]=0; } for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) if(map[i][j]) id[i][j]=++tot; } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(map[i][j]) { for(int k=0;k<4;k++) { int nx=i+dx[k],ny=j+dy[k],u=id[i][j],v=id[nx][ny]; if(nx&&nx<=n&&ny&&ny<=m&&map[nx][ny]) { a[u][v]=1;d[u][u]++; } } } for(int i=1;i<=tot;i++) for(int j=1;j<=tot;j++) c[i][j]=d[i][j]-a[i][j]; //cout<<tot<<endl; gauss(tot-1); return 0; }
相关文章推荐
- BZOJ 4031: [HEOI2015]小Z的房间
- BZOJ 4031: [HEOI2015]小Z的房间 [矩阵树定理 行列式取模]
- BZOJ 4031 HEOI2015 小Z的房间 Matrix-Tree定理
- BZOJ 4031: [HEOI2015]小Z的房间 高斯消元 MartixTree定理 辗转相除法
- BZOJ 4031 [HEOI2015]小Z的房间(Matrix-Tree定理)
- 【BZOJ 4031】: [HEOI2015]小Z的房间
- BZOJ 4031: [HEOI2015]小Z的房间 Matrix-Tree定理
- BZOJ 4031: [HEOI2015]小Z的房间(生成树计数)
- BZOJ 4031: [HEOI2015]小Z的房间
- bzoj 4031 [HEOI2015]小Z的房间 Matrix-tree定理
- BZOJ 4031: [HEOI2015]小Z的房间
- 【BZOJ 4031】 4031: [HEOI2015]小Z的房间 (Matrix-Tree Theorem)
- bzoj 4031: [HEOI2015]小Z的房间【矩阵树定理】
- bzoj 4031: [HEOI2015]小Z的房间 轮廓线dp
- BZOJ 4031: [HEOI2015]小Z的房间 矩阵树定理
- 【BZOJ 4031】[HEOI2015]小Z的房间 基尔霍夫矩阵
- BZOJ 4031([HEOI2015]小Z的房间-矩阵树定理+辗转相除)
- bzoj 4031: [HEOI2015]小Z的房间 (矩阵树定理+高斯消元)
- BZOJ 4031: [HEOI2015]小Z的房间 Matrix-Tree定理+辗转相除法求行列式的值(高斯消元)
- BZOJ:4031: [HEOI2015]小Z的房间