3 3 2 -1 0 0 1 1 0 3 2 -1 0 0 0 1 0 3 1 -1 0 0 1 1 0
3 1 -1
题意:平面上有n个sb,然后某一个变身,他会导致距离离他r之内的sb也变身
(他和这个sb之间不能有别的sb),两个相互影响的sb之间连线,最后这种图的形状
有几种.
建图的时候n^3枚举判断两个sb之间有没有别的sb,没有这两个点就可以连边,然后
跑一下生成树计数.貌似没什么坑.
#include <bits/stdc++.h> using namespace std; #define maxn 311 #define mod 10007 #define eps 1e-10 int a[maxn][maxn]; int cnt; int n; double r; struct point { double x, y; point (double _x = 0, double _y = 0) : x(_x), y(_y) {} point operator - (point a) const { return point (x-a.x, y-a.y); } bool operator < (const point &a) const { return x < a.x || (x == a.x && y < a.y); } }p[maxn]; int dcmp (double x) { if (fabs (x) < eps) return 0; else return x < 0 ? -1 : 1; } double cross (point a, point b) { return a.x*b.y-a.y*b.x; } double dot (point a, point b) { return a.x*b.x + a.y*b.y; } bool OnSegment (point a1, point a2, point p) {//判断点p是不是在线段a1a2上 if (dcmp (cross (a1-p, a2-p)) == 0 && dcmp (dot (a1-p, a2-p)) <= 0) return 1; return 0; } long long det () //按列化为下三角 { long long res = 1; for(int i = 0; i < n; ++i) { if (!a[i][i]) { bool flag = false; for (int j = i + 1; j < n; ++j) { if (a[j][i]) { flag = true; for (int k = i; k < n; ++k) { swap (a[i][k], a[j][k]); } res = -res; break; } } if (!flag) { return 0; } } for (int j = i + 1; j < n; ++j) { while (a[j][i]) { long long t = a[i][i] / a[j][i]; for (int k = i; k < n; ++k) { a[i][k] = (a[i][k] - t * a[j][k]) % mod; swap (a[i][k], a[j][k]); } res = -res; } } res *= a[i][i]; res %= mod; } return (res+mod)%mod; } double dis (point a, point b) { double x = a.x-b.x, y = a.y-b.y; return x*x+y*y; } int main() { //freopen("in.txt", "r", stdin); int t; scanf ("%d", &t); while (t--) { scanf ("%d%lf", &n, &r); for (int i = 0; i < n; i++) { scanf ("%lf%lf", &p[i].x, &p[i].y); } memset (a, 0, sizeof a); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) if (i != j) { if (dis (p[i], p[j]) > r*r) continue; bool flag = 0; for (int k = 0; k < n; k++) if (k != i && k != j) { if (OnSegment (p[i], p[j], p[k])) { flag = 1; break; } } if (!flag) { a[i][i]++; a[i][j] = -1; } } } n--; long long ans = det (); printf ("%lld\n", (ans > 0 ? ans : -1)); } return 0; }