http://acm.timus.ru/problem.aspx?space=1&num=1627
给一个无向图,问可以有多少生成树
参照 周冬《生成树的计数及其应用》
代码:
import java.io.File; import java.io.FileNotFoundException; import java.math.BigDecimal; import java.math.BigInteger; import java.util.Scanner; class Fraction { public BigInteger x; public BigInteger y; public Fraction(int xx, int yy) { x = BigInteger.valueOf(xx); y = BigInteger.valueOf(yy); } static public BigInteger gcd(BigInteger x, BigInteger y) { if (x.mod(y).compareTo(BigInteger.ZERO) == 0) { return y; } else { return gcd(y, x.mod(y)); } } public Fraction add(Fraction f) { Fraction ff = new Fraction(0, 1); ff.y = this.y.multiply(f.y); ff.x = this.x.multiply(f.y).add(this.y.multiply(f.x)); BigInteger z = Fraction.gcd(ff.x, ff.y); ff.x = ff.x.divide(z); ff.y = ff.y.divide(z); return ff; } public Fraction subtract(Fraction f) { Fraction ff = new Fraction(0, 1); ff.y = this.y.multiply(f.y); ff.x = this.x.multiply(f.y).subtract(this.y.multiply(f.x)); BigInteger z = Fraction.gcd(ff.x, ff.y); ff.x = ff.x.divide(z); ff.y = ff.y.divide(z); return ff; } public Fraction multiply(Fraction f) { Fraction ff = new Fraction(0, 1); ff.y = this.y.multiply(f.y); ff.x = this.x.multiply(f.x); BigInteger z = Fraction.gcd(ff.x, ff.y); ff.x = ff.x.divide(z); ff.y = ff.y.divide(z); return ff; } public Fraction divide(Fraction f) { Fraction ff = new Fraction(0, 1); ff.y = this.y.multiply(f.x); ff.x = this.x.multiply(f.y); BigInteger z = Fraction.gcd(ff.x, ff.y); ff.x = ff.x.divide(z); ff.y = ff.y.divide(z); if (ff.y.compareTo(BigInteger.ZERO) < 0) { ff.y = ff.y.abs(); ff.x = ff.x.multiply(BigInteger.valueOf(-1L)); } return ff; } public boolean equals(Fraction f) { if (this.x.equals(f.x) && this.y .equals(f.y)) { return true; } return false; } } public class Main { /** * @param args * @throws FileNotFoundException */ public static int N = 100; public static void main(String[] args) throws FileNotFoundException { // TODO Auto-generated method stub Scanner in = new Scanner(System.in); Fraction[][] a = new Fraction[N][N]; for (int i = 0; i < N; ++i) { for (int j = 0; j < N; ++j) { a[i][j] = new Fraction(0, 1); } } int[][] k = new int[N][N]; int[] X = { 0, 0, -1, 1 }; int[] Y = { 1, -1, 0, 0 }; int n = in.nextInt(); int m = in.nextInt(); int ln = 0; for (int i = 0; i < n; ++i) { String s = in.next(); for (int j = 0; j < m; ++j) { if (s.charAt(j) == '.') { k[i][j] = (++ln); } } } for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) { if (k[i][j] > 0) { for (int w = 0; w < 4; ++w) { int x = i + X[w]; int y = j + Y[w]; if (x >= 0 && x < n && y >= 0 && y < m && k[x][y] > 0) { a[k[i][j]][k[x][y]] = new Fraction(-1, 1); a[k[i][j]][k[i][j]] = a[k[i][j]][k[i][j]] .add(new Fraction(1, 1)); } } } } } if (ln > 1) { System.out.println(valueOfMatrix(a, ln - 1)); }else{ System.out.println(1); } } public static BigInteger valueOfMatrix(Fraction[][] a, int n) { // TODO Auto-generated method stub BigInteger MOD = BigInteger.valueOf(1000000000L); dfs(a, n); Fraction v = new Fraction(1, 1); for (int i = 1; i <= n; ++i) { v = v.multiply(a[i][i]); } return v.x.mod(MOD); } public static void dfs(Fraction[][] a, int n) { if (n == 1) return; int l = n; Fraction fractionZORE = new Fraction(0, 1); while (l >= 1 && a[l][n].equals(fractionZORE)) { --l; } if (l < 1) { dfs(a, n - 1); } else { if (l < n) { for (int j = 1; j <= n; ++j) { Fraction z = a[l][j]; a[l][j] = a[n][j]; a[n][j] = z; } } for (int i = 1; i < n; ++i) { if (!a[i][n].equals(fractionZORE)) { Fraction z = a[i][n].divide(a[n][n]); for (int j = 1; j <= n; ++j) { a[i][j] = a[i][j].subtract(a[n][j].multiply(z)); } } } dfs(a, n - 1); } } }