[BZOJ4031][HEOI2015]小Z的房间(矩阵树定理+高斯消元)
来源:互联网 发布:vue.js dotnet core 编辑:程序博客网 时间:2024/04/28 08:08
=== ===
这里放传送门
=== ===
题解
没错这就是个裸题
矩阵树定理: 定义一个图的基尔霍夫矩阵为:
其中A[i][j]=⎧⎩⎨d[i],−1,i=ji≠j d[i] 表示点i 的度。 对于无向图来说,这个矩阵的任何一个n-1阶主子式的行列式的值就是这个图的不同生成树个数。
其中n-1阶主子式表示在矩阵中任意去掉标号相同的一行和一列以后剩下的子矩阵
但是这题模数实在是太 ! 恶 ! 心 ! 了!!!
ATP尝试了N多种方法包括什么最小公倍数乱搞。。
最后还是上网扒出了这种类似辗转相除的方法。。
原理在ATP写高斯消元的板子里有详细的解释[戳这里],ATP就懒得再打一遍了。。
代码
#include<cmath>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const double eps=1e-8;const long long Mod=1e9;int n,m,mp[20][20],d[4][2]={{0,1},{1,0},{-1,0},{0,-1}},c[20][20],cnt;long long ans,A[110][110],mak;long long Abs(long long x){return (x<0)?-x:x;}long long gcd(long long a,long long b){ long long r=a%b; while (r!=0){a=b;b=r;r=a%b;} return b;}long long get_LCM(long long a,long long b){ return (a/gcd(a,b)*b);}void addedge(int x,int y){ int u,v,a,b; a=c[x][y]; for (int i=0;i<4;i++){ u=x+d[i][0];v=y+d[i][1]; if (c[u][v]!=0){ b=c[u][v];A[a][a]++;A[a][b]=-1; } }}/*void Gauss_Eli(int n){ int num; for (int i=1;i<=n;i++){ num=i; for (int j=i+1;j<=n;j++) if (Abs(A[j][i])>Abs(A[num][i])) num=j; for (int j=1;j<=n;j++) swap(A[i][j],A[num][j]); for (int j=i+1;j<=n;j++) if (A[j][i]!=0){ long long lcm=get_LCM(A[i][i],A[j][i]),ta,tb; ta=lcm/Abs(A[j][i]);tb=lcm/Abs(A[i][i]); if (A[j][i]*A[i][i]<0) tb=-tb; for (int k=1;k<=n;k++) A[j][k]=(ta*A[j][k]-tb*A[i][k])%Mod; } }}*/void Gauss_Eli(int n){ int num; for (int i=1;i<=n;i++){ num=i; for (int j=i+1;j<=n;j++) if (Abs(A[j][i])>Abs(A[num][i])) num=j; if (num!=i) mak^=1; for (int j=1;j<=n;j++) swap(A[i][j],A[num][j]); for (int j=i+1;j<=n;j++) while (A[j][i]!=0){ long long tmp=A[j][i]/A[i][i]; for (int k=1;k<=n;k++)//做完一次操作以后A[j][i]相当于对A[i][i]取模了 A[j][k]=(A[j][k]+Mod-tmp*A[i][k]%Mod)%Mod; if (A[j][i]==0) break; mak^=1;//注意要维护取反标记,不能直接取绝对值 for (int k=1;k<=n;k++) swap(A[j][k],A[i][k]); } }}int main(){ scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) for (int j=1;j<=m;j++){ char s=getchar(); while (s!='.'&&s!='*') s=getchar(); if (s=='*') mp[i][j]=1; else c[i][j]=++cnt; } for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) if (mp[i][j]!=1) addedge(i,j); Gauss_Eli(cnt-1);ans=1; for (int i=1;i<cnt;i++) ans=(ans*A[i][i])%Mod; if (mak==1) ans=Mod-ans;//因为是取模运算所以一定要注意正负 ans=(ans+Mod)%Mod; printf("%I64d\n",ans); return 0;}
0 0
- 【bzoj4031】 HEOI2015小Z的房间 矩阵树定理
- [BZOJ4031][HEOI2015]小Z的房间(矩阵树定理+高斯消元)
- 【HEOI2015】【BZOJ4031】小Z的房间
- bzoj4031【HEOI2015】小Z的房间
- bzoj4031 [HEOI2015]小Z的房间
- 【HEOI2015】bzoj4031 小z的房间
- BZOJ4031: [HEOI2015]小Z的房间
- bzoj4031: [HEOI2015]小Z的房间
- 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的房间 基尔霍夫矩阵
- BZOJ 4031: [HEOI2015]小Z的房间 Matrix-Tree定理+辗转相除法求行列式的值(高斯消元)
- BZOJ 4031: [HEOI2015]小Z的房间
- 4031: [HEOI2015]小Z的房间
- BZOJ4031——HEOI小z的房间
- ElasticSearch2.4.2安装search-guard插件
- CSS垂直居中的11种实现方式
- Java_java.lang.UnsupportedClassVersionError
- linux下gcc编译conio.h问题
- Java 基础【02】 Super 用法
- [BZOJ4031][HEOI2015]小Z的房间(矩阵树定理+高斯消元)
- git的三个核心概念(版本库,工作区,暂存区)
- Maven_Nexus_install
- python 字符串截取
- 【NOI2017模拟4.5】无限棋盘【哈希,字符串,倍增】
- MyEclipse中Maven的配置
- device eth0 does not seem to be present, delaying initialization
- (一)图像坐标:我想和世界坐标谈谈(A) 【计算机视觉学习笔记--双目视觉几何框架系列】
- Could not create ActionMapper: WebWork will *not* work!