Topic Links:
http://www.lydsy.com/JudgeOnline/problem.php?id=4031
Exercises
The Matrix-tree theorem solves the problem of spanning tree counting, in which the Gaussian elimination method is used to find the upper triangular matrix, in which the inverse method is used.
Code:
#include <iostream>#include<cstdio>#include<cstring>using namespacestd;Const intMoD =1e9;Const intMAXN =111; typedefLong LongLL;intN, m, tot;CharSTR[MAXN][MAXN];intMP[MAXN][MAXN]; LL C[MAXN][MAXN];Const intDx[] = {0,0,-1,1 };Const intDy[] = {-1,1,0,0 }; LL Det (intN) {LL ret=1; intf =1; for(inti =1; I <= N; i++) { for(intj =1; J <= N; J + +) {C[i][j]= (C[i][j]% mod + MoD)%MoD; } } for(inti =1; I <= N; i++) { for(intj = i +1; J <= N; J + +) { intA = C[i][i], B =C[j][i]; while(b!=0) {LL T= A/b; A = A%b; swap (A, b); for(intK = i; K <= N; k++) {C[i][k]= (C[i][k]-t*c[j][k]% mod + MoD)%MoD; } for(intK = i; K <= n;k++) {swap (c[i][k], c[j][k]); } f= -F; }} RET= Ret*c[i][i]%MoD; } if(f = =-1) ret = ((-ret)%mod + MoD)%MoD; returnret;}voidinit () {tot=0; memset (C,0,sizeof(C));}intMain () { while(SCANF ("%d%d", &n, &m) = =2&&N) {init (); for(inti =0; I < n; i++) scanf ("%s", Str[i]); for(inti =0; I < n; i++) { for(intj =0; J < M; J + +) { if(Str[i][j] = ='.') {Mp[i][j]= ++tot; } } } for(inti =0; I < n; i++) { for(intj =0; J < M; J + +) { if(Str[i][j] = ='.') { for(intt =0; T <4; t++) { intII = i + dx[t], JJ = j +Dy[t]; if(ii <0|| II >= n | | JJ <0|| JJ >= m | | STR[II][JJ] = ='*')Continue; C[MP[I][J]][MP[I][J]]++; C[MP[I][J]][MP[II][JJ]]--; } }}} LL ans=det (Tot-1); printf ("%lld\n", ans); } return 0;}
Bzoj 4031: [HEOI2015] small Z room matrix-tree theorem