【SG博弈】HDU 5299 Circles Game

通道:http://acm.hdu.edu.cn/showproblem.php?pid=5299

题意:n个不相交相切的圆,每次操作删圆及其内部的圆,不能删者败。

思路:建边,然后树上SG即可。

代码:

  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 } 
View Code

 

posted @ 2015-07-21 21:34  mithrilhan  阅读(264)  评论(0编辑  收藏  举报