【SG博弈】HDU 5299 Circles Game
通道:http://acm.hdu.edu.cn/showproblem.php?pid=5299
题意:n个不相交相切的圆,每次操作删圆及其内部的圆,不能删者败。
思路:建边,然后树上SG即可。
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <cstring> 3 #include <set> 4 #include <algorithm> 5 6 using namespace std; 7 8 const int MAX_N = 20007; 9 const int INF = 0x3f3f3f3f; 10 11 struct Node { 12 int x, y, r, id; 13 Node () { 14 15 } 16 Node (int _x, int _y, int _r, int _i) { 17 x = _x; 18 y = _y; 19 r = _r; 20 id = _i; 21 } 22 bool operator < (const Node &rhs) const { 23 return x < rhs.x || x == rhs.x && y < rhs.y; 24 } 25 }; 26 27 struct Pst { 28 int v, nxt; 29 Pst () { 30 31 } 32 Pst (int _v, int _n) { 33 v = _v; 34 nxt = _n; 35 } 36 }; 37 38 Node a[MAX_N], b[MAX_N]; 39 bool root[MAX_N]; 40 int era[MAX_N], head[MAX_N], edgecnt, dp[MAX_N]; 41 set<Node> s; 42 Pst G[MAX_N << 2]; 43 44 bool cmp(Node a, Node b) { 45 return a.r < b.r; 46 } 47 48 void init() { 49 memset(head, -1, sizeof head); 50 edgecnt = 0; 51 } 52 53 void add(int u, int v) { 54 G[edgecnt] = Pst(v, head[u]); 55 head[u] = edgecnt++; 56 } 57 58 void dfs(int u, int fa) { 59 dp[u] = 0; 60 for (int i = head[u]; ~i; i = G[i].nxt) { 61 dfs(G[i].v, u); 62 dp[u] ^= (1 + dp[G[i].v]); 63 } 64 } 65 66 int sqr(int x) { 67 return x * x; 68 } 69 70 int main() { 71 int T; 72 scanf("%d", &T); 73 while(T-- > 0) { 74 int n; 75 scanf("%d", &n); 76 for (int i = 0; i < n; ++i) { 77 scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].r); 78 a[i].id = i; 79 b[i] = a[i]; 80 } 81 sort(a, a + n, cmp); 82 s.clear(); 83 init(); 84 memset(root, 1, sizeof root); 85 for (int i = 0; i < n; ++i) { 86 set<Node>::iterator l = s.lower_bound(Node(a[i].x - a[i].r, -INF, a[i].r, a[i].id)); 87 set<Node>::iterator r = s.upper_bound(Node(a[i].x + a[i].r, INF, a[i].r, a[i].id)); 88 int cnt = 0; 89 for (set<Node>::iterator it = l; it != r && it != s.end(); ++it) { 90 if (sqr(a[i].x - (*it).x) + sqr(a[i].y - (*it).y) <= sqr(a[i].r)) { 91 add(a[i].id, (*it).id); 92 root[(*it).id] = 0; 93 era[cnt++] = (*it).id; 94 } 95 } 96 for (int j = 0; j < cnt; ++j) s.erase(b[era[j]]); 97 s.insert(a[i]); 98 } 99 int ans = 0; 100 for (int i = 0; i < n; ++i) { 101 if (root[i]) { 102 dfs(i, -1); 103 ans ^= (1 + dp[i]); 104 } 105 } 106 if (ans) puts("Alice"); 107 else puts("Bob"); 108 } 109 return 0; 110 }