Question address: http://acm.hdu.edu.cn/showproblem.php? PID = 1, 4305
Question: Give You N points. If the distance between the two points is less than or equal to R, you can even get an edge to survive the number of trees.
Question:
For an undirected graph G, its Kirchhoff matrix C is defined as its degree matrix D minus its adjacent matrix. Obviously, this definition satisfies the nature described just now.
With the Kirchhoff matrix tool, we can introduce the matrix-tree theorem:
The matrix rules are as follows:
1. The degree of the element on the primary diagonal to this node
2. For the Element Matrix (I, j) {I! = J },
(1) If node I is connected to node J, the value of matrix (I, j) is-K, where the K value is the number of parallel edges from node I to node J. If this graph is a simple graph, that is, if there is no parallel edge between two points, the value is-1.
(2) If node I and node J are not connected at all, the value of matrix (I, j) is 0.
Method: For an undirected graph G, the number of spanning trees is equal to the absolute value of the determinant of any n-1 primary-child type in the Kirchhoff matrix. N-1 R, delete the new matrix of row R and column R of column C at the same time, which is expressed by Cr. Complexity: O (N ^ 3)
AC code:
# Include <iostream> # include <vector> # include <list> # include <deque> # include <queue> # include <iterator> # include <stack> # include <map> # include <set> # include <algorithm> # include <cctype> # include <cstdio> # include <cstdlib> # include <cstring> # include <string> # include <cmath> using namespace STD; typedef long ll; const int n = 302; const ll mod = 10007; const int INF = 0x3f3f3f; const double Pi = ACOs (-1.0); cons T double EPS = 1e-7; using namespace STD; int a [n] [N], MP [N] [N]; int N; Double R; struct node {Double X, y; node () {}; node (double A, double B): X (A), y (B) {} void input () {scanf ("% lf", & X, & Y);} friend node operator-(const node & A, const node & B) {return node (. x-b.x,. y-b.y);} p [N]; double DIS (node A, Node B) {return (. x-b.x) * (. x-b.x) +. y-b.y) * (. y-b.y);} bool love (int I, int K, Int J) {double T = (P [I]. x-P [K]. x) * (p [J]. y-P [K]. y)-(P [I]. y-P [K]. y) * (p [J]. x-P [K]. x); If (FABS (t-0)> 1e-6) return false; // t = (P [I]. x-P [K]. x) * (p [J]. x-P [K]. x) + (P [I]. y-P [K]. y) * (p [J]. y-P [K]. y); If (T> = 0) return false; // return true not in the middle of ij;} int ext_gcd (int A, int B, Int & X, Int & Y) {int T, RET; If (! B) {x = 1, y = 0; return a;} ret = ext_gcd (B, A % B, x, y); t = x, x = Y, y = T-A/B * Y; return ret;} int Gauss (int r, int c) {int I = 1, K, J, CNT = 1; for (j = 1; j <= C; j ++) {int id = I; for (k = I; k <= r; k ++) if (A [k] [J]> 0) {id = K; break;} if (a [ID] [J]) {If (ID! = I) {for (k = J; k <= C; k ++) Swap (A [I] [K], a [ID] [k]);} for (k = I + 1; k <= r; k ++) {If (! A [k] [J]) continue; CNT = (CNT * A [I] [J]) % MOD; For (INT L = C; L> = J; l --) {A [k] [l] = (a [k] [l] * A [I] [J]-A [I] [l] * A [k] [J ]) % MOD; A [k] [l] = (a [k] [l] + mod) % MOD;} I ++ ;}} int X, Y; ext_gcd (CNT, Mod, x, y); X = (X % mod + mod) % MOD; // X is the reverse element of CNT for MOD (I = 1; I <= r; I ++) x = (x * A [I] [I]) % MOD; Return (x + mod) % MOD;} int main () {int T, I, J, K, CAS; scanf ("% d", & T); While (t --) {scanf ("% d % lf ", & N, & R); for (I = 1; I <= N; I ++) P [I]. input (); memset (A, 0, sizeof (a); memset (MP, 0, sizeof (MP); double RR = r * R; for (I = 1; I <= N; I ++) for (j = I + 1; j <= N; j ++) {If (DIS (P [I], p [J])> RR) continue; int flag = 1; for (k = 1; k <= N; k ++) {if (I = k | j = k) continue; // operator overload is used at this point, and the result times out, if (Love (I, K, j) // K is defined as if (Love (I, K, j) in the middle of the IJ line segment {flag = 0; break ;}} if (FLAG) {MP [I] [J] = MP [J] [I] = 1; A [I] [J] --; A [J] [I] --; A [I] [I] ++; A [J] [J] ++ ;}}/* cout <Endl; for (I = 1; I <= N; I ++) {for (j = 1; j <= N; j ++) printf ("% d", MP [I] [J]); cout <Endl ;}cout <Endl; for (I = 1; I <= N; I ++) {for (j = 1; j <= N; j ++) printf ("% d", a [I] [J]); cout <Endl;} */INT XH = Gaussian (n-1, n-1 ); if (XH = 0) puts ("-1"); else printf ("% d \ n", XH) ;}return 0 ;} /* 33 2-1 00 11 03 2-1 00 01 03 1-1 00 11 0 */