HDU 5936 朋友

 

题意为给出一棵n个节点的树,这棵树的每条边有一个权值,这个权值只可能是0或1。 在一局游戏开始时,会确定一个节点作为根。

当一方操作时,他们需要先选择一个不为根的点,满足该点到其父亲的边权为1; 然后找出这个点到根节点的简单路径,将路径上所有边的权值翻转(即0变成1,1 变成0 )。 

当一方无法操作时(即所有边的边权均为0),另一方就获得了胜利。 

为了让游戏更有趣味性,在每局之间可能会有修改边权的操作,而且每局游戏指 定的根节点也可能是不同的。 

具体来说,修改边权和进行游戏的操作一共有m个,具体如下: 

  • 0 x 表示询问对于当前的树,如果以x为根节点开始游戏,哪方会获得胜利.
  • 1 x y z 表示将x和y之间的边权修改为z。

思路是考虑所有和根节点相连的边。若某条边为0,则先手将这条边变为1后,后手总能再将这条边变为0。

所以游戏只和根节点相连的为1的边的个数有关系。

代码如下:

 1 #include"cstdio"
 2 #include"iostream"
 3 #include"cstring"
 4 #include"algorithm"
 5 #include"cstdlib"
 6 #include"vector"
 7 #include"set"
 8 using namespace std;
 9 typedef long long LL;
10 const int MAXN=40010;
11 
12 int edgesum[MAXN];
13 set<int> G[MAXN];
14 int main()
15 {
16 #ifdef LOCAL
17     freopen("in.txt","r",stdin);
18     //freopen("out.txt","w",stdout);
19 #endif
20     int t;
21     scanf("%d",&t);
22     for(int tt=1;tt<=t;tt++)
23     {
24         memset(edgesum,0,sizeof(edgesum));
25         int n,m;
26         scanf("%d%d",&n,&m);
27         for(int i=1;i<=n;i++)
28             G[i].clear();
29         for(int i=1;i<=n-1;i++)
30         {
31             int x,y,z;
32             scanf("%d%d%d",&x,&y,&z);
33             if(z)
34             {
35                 G[x].insert(y);
36                 G[y].insert(x);
37                 edgesum[x]++;
38                 edgesum[y]++;
39             }
40         }
41         for(int i=1;i<=m;i++)
42         {
43             int op;
44             int x,y,z;
45             scanf("%d",&op);
46             if(op)
47             {
48                 scanf("%d%d%d",&x,&y,&z);
49                 if(z==1 && G[x].count(y)==0)
50                 {
51                     G[x].insert(y);
52                     G[y].insert(x);
53                     edgesum[x]++;
54                     edgesum[y]++;
55                 }
56                 if(z==0 && G[x].count(y)!=0)
57                 {
58                     G[x].erase(y);
59                     G[y].erase(x);
60                     edgesum[x]--;
61                     edgesum[y]--;
62                 }
63             }
64             if(!op)
65             {
66                 int x;
67                 scanf("%d",&x);
68                 if(edgesum[x]%2) printf("Girls win!\n");
69                 else printf("Boys win!\n");
70             }
71         }
72     }
73     return 0;
74 }

 

posted @ 2017-04-16 18:00  HuaZhang  阅读(186)  评论(0编辑  收藏  举报