【HDOJ】4305 Lightning

1. 题目描述
当一个结点lightning后,可以向其周围距离小于等于R的结点传播lightning。然后以该结点为中心继续传播。以此类推,
问最终形成的树形结构有多少个。

2. 基本思路
生成树级数模板题目。
Matrix-Tree定理(Kirchhoff矩阵-树定理):
1) G的度数矩阵D[G]是一个n*n的矩阵,并且满足:当i≠j时,dij=0;当i=j时,dij等于vi的度数;
2) G的邻接矩阵A[G]也是一个n*n的矩阵, 并且满足:如果vi、vj之间有边直接相连,则aij=1,否则为0。
定义Kirchhoff矩阵C[G] = D[G]-A[G]。不同生成树的个数是C[G]的任何一个n-1阶主子式的行列式的绝对值。
行列式值通过化上三角可求。除法使用逆元可求。

3. 代码

  1 /* 4305 */
  2 #include <iostream>
  3 #include <sstream>
  4 #include <string>
  5 #include <map>
  6 #include <queue>
  7 #include <set>
  8 #include <stack>
  9 #include <vector>
 10 #include <deque>
 11 #include <bitset>
 12 #include <algorithm>
 13 #include <cstdio>
 14 #include <cmath>
 15 #include <ctime>
 16 #include <cstring>
 17 #include <climits>
 18 #include <cctype>
 19 #include <cassert>
 20 #include <functional>
 21 #include <iterator>
 22 #include <iomanip>
 23 using namespace std;
 24 //#pragma comment(linker,"/STACK:102400000,1024000")
 25 
 26 #define sti                set<int>
 27 #define stpii            set<pair<int, int> >
 28 #define mpii            map<int,int>
 29 #define vi                vector<int>
 30 #define pii                pair<int,int>
 31 #define vpii            vector<pair<int,int> >
 32 #define rep(i, a, n)     for (int i=a;i<n;++i)
 33 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
 34 #define clr                clear
 35 #define pb                 push_back
 36 #define mp                 make_pair
 37 #define fir                first
 38 #define sec                second
 39 #define all(x)             (x).begin(),(x).end()
 40 #define SZ(x)             ((int)(x).size())
 41 #define lson            l, mid, rt<<1
 42 #define rson            mid+1, r, rt<<1|1
 43 
 44 typedef struct Point {
 45     int x, y;
 46     
 47     Point() {}
 48     Point(int x, int y):
 49         x(x), y(y) {}
 50     
 51     Point operator - (const Point& a) const {
 52         return Point(x-a.x, y-a.y);
 53     }
 54     
 55     int operator ^ (const Point& a) const {
 56         return x*a.y - y*a.x;
 57     }
 58     
 59 } Point;
 60 
 61 typedef struct Segment {
 62     Point s, e;
 63     
 64     Segment() {}
 65     Segment(Point s, Point e):
 66         s(s), e(e) {}
 67         
 68 } Segment;
 69 
 70 bool onSegment(Point p, Point a, Point b) {
 71     return ((a-p)^(b-p))==0 && (p.x-a.x)*(p.x-b.x)<=0 && (p.y-a.y)*(p.y-b.y)<=0;
 72 }
 73 
 74 int Length(Point a, Point b) {
 75     return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y);
 76 }
 77 
 78 
 79 #define LL __int64
 80 
 81 const int mod = 10007;
 82 
 83 
 84 LL Pow(LL base, LL n, LL mod) {
 85     LL ret = 1;
 86     
 87     while (n) {
 88         if (n & 1)
 89             ret = ret * base % mod;
 90         base = base * base % mod;
 91         n >>= 1;
 92     }
 93     
 94     return ret;
 95 }
 96 
 97 int Inv(int x) {
 98     return Pow(x, mod-2, mod);
 99 }
100 
101 typedef struct mat_t {
102     static const int maxn = 305;
103     int m[maxn][maxn];
104     
105     void init() {
106         memset(m, 0, sizeof(m));
107     }
108     
109     int det(int n) {
110         rep(i, 0, n)
111             rep(j, 0, n)
112                 m[i][j] = (m[i][j]%mod+mod) % mod;
113         int ret = 1;
114         
115         rep(i, 0, n) {
116             rep(j, i, n) {
117                 if (m[j][i]) {
118                     rep(k, i, n)
119                         swap(m[i][k], m[j][k]);
120                     if (i != j)
121                         ret = (-ret + mod) % mod;
122                     break;
123                 }
124             }
125             
126             if (m[i][i] == 0) {
127                 ret = -1;
128                 break;
129             }
130             
131             rep(j, i+1, n) {
132                 int tmp = m[j][i] * Inv(m[i][i]) % mod;
133                 rep(k, i, n)
134                     m[j][k] = ((m[j][k] - m[i][k]*tmp%mod) % mod + mod) % mod;
135             }
136             
137             ret = ret * m[i][i] % mod;
138         }
139         
140         return ret;
141     }
142 } mat_t;
143 
144 const int maxn = 305;
145 Point P[maxn];
146 int n, R, R2;
147 bool M[maxn][maxn];
148 mat_t base;
149 
150 bool judge(int i, int j) {
151     if (Length(P[i], P[j]) > R2)
152         return false;
153     
154     rep(k, 0, n) {
155         if (k==i || k==j)
156             continue;
157         
158         if (onSegment(P[k], P[i], P[j]))
159             return false;
160     }
161     
162     return true;
163 }
164 
165 void solve() {
166     R2 = R * R;
167     
168     memset(M, false, sizeof(M));
169     rep(i, 0, n) {
170         rep(j, i+1, n) {
171             if (judge(i, j))
172                 M[i][j] = M[j][i] = true;
173         }
174     }
175     
176     base.init();
177     rep(i, 0, n) {
178         rep(j, 0, n) {
179             if (i==j || !M[i][j])
180                 continue;
181             
182             ++base.m[i][i];
183             base.m[i][j] = -1;
184         }
185     }
186     
187     int ans = base.det(n-1);
188     
189     printf("%d\n", ans);
190 }
191 
192 int main() {
193     ios::sync_with_stdio(false);
194     #ifndef ONLINE_JUDGE
195         freopen("data.in", "r", stdin);
196         freopen("data.out", "w", stdout);
197     #endif
198     
199     int t;
200     
201     scanf("%d", &t);
202     while (t--) {
203         scanf("%d %d", &n, &R);
204         rep(i, 0, n)
205             scanf("%d %d", &P[i].x, &P[i].y);
206         solve();
207     }
208     
209     #ifndef ONLINE_JUDGE
210         printf("time = %d.\n", (int)clock());
211     #endif
212     
213     return 0;
214 }

4. 数据发生器

 1 import sys
 2 import string
 3 from random import randint
 4 
 5     
 6 def GenData(fileName):
 7     with open(fileName, "w") as fout:
 8         t = 20
 9         bound = 10**4
10         fout.write("%d\n" % (t))
11         for tt in xrange(t):
12             n = randint(1, 300)
13             r = randint(0, 20000)
14             fout.write("%d %d\n" % (n, r))
15             for i in xrange(n):
16                 x = randint(-bound, bound)
17                 y = randint(-bound, bound)
18                 fout.write("%d %d\n" % (x, y))
19                 
20         
21 def MovData(srcFileName, desFileName):
22     with open(srcFileName, "r") as fin:
23         lines = fin.readlines()
24     with open(desFileName, "w") as fout:
25         fout.write("".join(lines))
26 
27         
28 def CompData():
29     print "comp"
30     srcFileName = "F:\Qt_prj\hdoj\data.out"
31     desFileName = "F:\workspace\cpp_hdoj\data.out"
32     srcLines = []
33     desLines = []
34     with open(srcFileName, "r") as fin:
35         srcLines = fin.readlines()
36     with open(desFileName, "r") as fin:
37         desLines = fin.readlines()
38     n = min(len(srcLines), len(desLines))-1
39     for i in xrange(n):
40         ans2 = int(desLines[i])
41         ans1 = int(srcLines[i])
42         if ans1 > ans2:
43             print "%d: wrong" % i
44 
45             
46 if __name__ == "__main__":
47     srcFileName = "F:\Qt_prj\hdoj\data.in"
48     desFileName = "F:\workspace\cpp_hdoj\data.in"
49     GenData(srcFileName)
50     MovData(srcFileName, desFileName)
51     
52     

 

 

 

 

基本思路

你可能感兴趣的:(【HDOJ】4305 Lightning)