标签:span cep sele miss ++ mode head 取值 main
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6324
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 1234 Accepted Submission(s): 779
给出一棵有 N 个节点的树,给出每个节点的权值。
有Q ,T, D 三个人物。
Q 先在树里面取节点,要求是有边相连的节点只能选其一。
Q选完之后剩下的所有节点都属于 T。
比较 Q 和 T的节点权值异或和,如果 Q 的大则Q赢,反则 T 赢,平局输出 D
根据Q的选取条件,我们知道Q只能在这棵树上隔层取值。
那么我们可以把这棵树的节点分成两堆,第一堆是从第一层开始隔层取,每一层都把该层的节点全部取了。
那么如果这两堆不相等 Q 赢(他先选,选最大的那堆),如果两堆相等 平局。
因为如果出现两堆相等的情况,无论怎么交换节点,两个相同的值异或相同的值结果还是相等。
所以T不可能赢。
BFS跑一遍分成两堆即可。
AC code:
1 #include <set> 2 #include <map> 3 #include <cstdio> 4 #include <cstring> 5 #include <iostream> 6 #include <algorithm> 7 #define INF 0x3f3f3f3f 8 #define LL long long 9 using namespace std; 10 const int MAXN = 1e5+10; 11 struct Edge 12 { 13 int v, nxt; 14 }edge[MAXN<<1]; 15 int head[MAXN], cnt; 16 int w[MAXN]; 17 int ans_a, ans_b; 18 void init() 19 { 20 memset(head, -1, sizeof(head)); 21 ans_a = ans_b = 0; 22 cnt = 0; 23 } 24 25 void add(int from, int to) 26 { 27 edge[cnt].v = to; 28 edge[cnt].nxt = head[from]; 29 head[from] = cnt++; 30 } 31 32 33 34 void bfs(int x, bool no) 35 { 36 if(no){ 37 ans_a^=w[x]; 38 for(int i = head[x]; i != -1; i = edge[i].nxt){ 39 bfs(edge[i].v, !no); 40 } 41 } 42 else{ 43 ans_b^=w[x]; 44 for(int i =head[x]; i != -1; i = edge[i].nxt){ 45 bfs(edge[i].v, !no); 46 } 47 } 48 } 49 50 int main() 51 { 52 int N, u, v; 53 int T_case; 54 scanf("%d", &T_case); 55 while(T_case--){ 56 scanf("%d", &N); 57 init(); 58 for(int i = 1; i <= N; i++){ 59 scanf("%d", &w[i]); 60 } 61 62 for(int i = 1; i < N; i++){ 63 scanf("%d %d", &u, &v); 64 add(u, v); 65 } 66 ans_a = ans_b = 0; 67 bfs(1, true); 68 69 if(ans_a == ans_b) puts("D"); 70 else puts("Q"); 71 72 } 73 return 0; 74 }
2018 Multi-University Training Contest 3 Problem F. Grab The Tree 【YY+BFS】
标签:span cep sele miss ++ mode head 取值 main
原文地址:https://www.cnblogs.com/ymzjj/p/10295599.html