1627. Join

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);
		}
	}

}

  

你可能感兴趣的:(1627. Join)