【bzoj4031】 HEOI2015小Z的房间 矩阵树定理
2015-08-10 20:17
267 查看
第一次做矩阵树定理的题,其实就是记了个结论也没太看证明,然后学了学怎么用高斯消元求行列式,整数消元还真别扭,要用辗转相除,然后要注意取模的问题,一开始以为hzwer写麻烦了,后来想了想不加外面那句话会有问题,因为取模了。
#include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<iostream> #include<algorithm> #define mod 1000000000 using namespace std; int dx[4]={1,-1,0,0}; int dy[4]={0,0,1,-1}; long long a[110][110]; int n,m,id; int vis[110][110]; char s[110]; long long det(int n) { for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) a[i][j]=(a[i][j]+mod)%mod; long long ans=1,f=1; for (int i=1;i<=n;i++) { for (int j=i+1;j<=n;j++) { long long A=a[i][i],B=a[j][i]; while (B) { long long t=A/B;A%=B;swap(A,B); for (int k=i;k<=n;k++) a[i][k]=(a[i][k]-t*a[j][k]%mod+mod)%mod; for (int k=i;k<=n;k++) swap(a[i][k],a[j][k]); f=-f; } } if (!a[i][i]) return 0; ans=ans*a[i][i]%mod; } if (f==-1) ans=(mod-ans)%mod; return ans; } int main() { scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) { scanf("%s",s+1); for (int j=1;j<=m;j++) if (s[j]=='.') vis[i][j]=++id; } for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) if (vis[i][j]) for (int k=0;k<4;k++) { int x=i+dx[k],y=j+dy[k]; if (x<=0 || y<=0 || x>n || y>m || !vis[x][y]) continue; a[vis[i][j]][vis[i][j]]++;a[vis[i][j]][vis[x][y]]--; } printf("%lld\n",det(id-1)); return 0; }
相关文章推荐
- 扫盲文件完整性校验——关于散列值和数字签名
- 单片机IO口模拟SPI四种模式的程序
- LeetCode Find Minimum in Rotated Sorted Array系列
- LeetCode(25)Reverse Nodes in k-Group
- UNITY3D学习笔记14
- Scala入门到精通——第二十二节 高级类型 (一)
- 网站jcms流程分析
- LeetCode(25)Reverse Nodes in k-Group
- nginx封ip,禁用IP段的设置说明
- LVS之NAT模式简单示例
- I/O多路复用详解(三)
- json
- 《机器学习系统设计》之k-近邻分类算法
- Object-C类目、延展
- After Windows 10 upgrading deleting previous windows installation
- linux安装python遇到的问题
- hdu-1513-Palindrome
- Java toString()方法
- 无序线性搜索(Unordered Linear Search)
- UVA 12532-Interval Product(BIT)