• HDU5963-朋友


    题目描述

      B君在围观一群男生和一群女生玩游戏,具体来说游戏是这样的:
    给出一棵n个节点的树,这棵树的每条边有一个权值,这个权值只可能是0或1。 在一局游戏开始时,会确定一个节点作为根。接下来从女生开始,双方轮流进行 操作。 当一方操作时,他们需要先选择一个不为根的点,满足该点到其父亲的边权为1; 然后找出这个点到根节点的简单路径,将路径上所有边的权值翻转(即0变成1,1 变成0 )。 当一方无法操作时(即所有边的边权均为0),另一方就获得了胜利。
    如果在双方均采用最优策略的情况下,女生会获胜,则输出“Girls win!”,否则输 出“Boys win!”。
    为了让游戏更有趣味性,在每局之间可能会有修改边权的操作,而且每局游戏指 定的根节点也可能是不同的。
    具体来说,修改边权和进行游戏的操作一共有m个,具体如下:
    “0 x”表示询问对于当前的树,如果以x为根节点开始游戏,哪方会获得胜利。
    “1 x y z ”表示将x和y之间的边的边权修改为z。
    B君当然知道怎么做啦!但是他想考考你。

    Input

    包含至多5组测试数据。
    第一行有一个正整数,表示数据的组数。
    接下来每组数据第一行,有二个空格隔开的正整数n,m,分别表示点的个数,操 作个数。保证n,m< 40000。
    接下来n-1行,每行三个整数x,y,z,表示树的一条边。保证1<x<n, 1<y< n, 0 <= z <= 1。
    接下来m行,每行一个操作,含义如前所述。保证一定只会出现前文中提到的两 种格式。
    对于操作0,保证1 <= x <= n ;对于操作1,保证1 <= x <= n, 1 <= y <= n, 0 <= z <= 1,保证树上存在一条边连接x和y。

    Output

    对于每组数据的每一个询问操作,输出一行“Boys win!”或者“Girls win!”。

    Sample Input

    2
    2 3
    1 2 0
    0 1
    1 2 1 1
    0 2
    4 11
    1 2 1
    2 3 1
    3 4 0
    0 1
    0 2
    0 3
    0 4
    1 2 1 0
    0 1
    0 2
    0 3
    1 3 4 1
    0 3
    0 4
    Sample Output
    Boys win!
    Girls win!
    Girls win!
    Boys win!
    Girls win!
    Boys win!
    Boys win!
    Girls win!
    Girls win!
    Boys win!
    Girls win! 
    思路分析:
      关于这道题我们可以考虑,设如果当前要反转的节点不是与当前游戏的根相连的话,在一方操作完之后,该节点上方所有的边的边权都会
    发生翻转,例如下图所示,我们设3-7初始边权为1,0-3为0,在翻转完7号节点之后,0-3之间的边权变为了1,则之后后手可以继续翻转3
    号节点以复原除3-7外其他被修改的边权,这就相当于我们以把一条边权为1的边变为0为代价将游戏的当前操作方又变回了原来的先手。那么
    若这么考虑下去,先手必输。

    但我们还需要考虑,后手要翻转边是有条件的,及该边与其父节点的边权为1,即1.有父节点,2.边权为1.
    在先手翻完一条边后,后手应该从先手所翻转的点向上找到第一个可以翻转的点进行复原,但如果上面的点是根节点的话,后手将无法操作,
    只好从一条新的树边开始,那么此时先手边掌握了主动权,直到再次遇到一条与根相连边权为1的点为止。如果主动权变换次数为偶数了话,
    最终还是后手,即男孩赢,反之女孩赢。那么对于每个节点,只需统计与他相连的且边权为1的节点个数,当为偶数时,boy win,反之,
    girl win。最后注意修改即可。
    附上代码
     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 const int N=1e6+10;
     5 int Head[N],tot,sum[N];
     6 struct Node{
     7     int next,to,dis;
     8 }edge[N]; 
     9 void Add(int x,int y,int z){
    10     edge[++tot].to=y;
    11     edge[tot].next=Head[x];
    12     edge[tot].dis=z;
    13     Head[x]=tot;
    14 }
    15 void update(int x,int y,int z){
    16     for(int i=Head[x];i;i=edge[i].next){
    17         int v=edge[i].to;
    18         if(v==y){
    19             if(edge[i].dis==z) return;  //如果修改值相同就不用改了. 
    20             else if(z){
    21                 sum[x]++;
    22                 edge[i].dis++;
    23             }
    24             else{
    25                 sum[x]--;
    26                 edge[i].dis--;
    27             }
    28             return;
    29         }
    30     }
    31 }
    32 void work(){
    33     int x;
    34     scanf("%d",&x);
    35     if(sum[x]%2==0) printf("Boys win!
    ");
    36     else printf("Girls win!
    ");
    37 }
    38 int main(){
    39     int T;
    40     scanf("%d",&T);
    41     while(T--){
    42         memset(Head,0,sizeof(Head)); //多组数据需要更新。 
    43         memset(edge,0,sizeof(edge));
    44         memset(sum,0,sizeof(sum));
    45         tot=0;
    46         int n,m;
    47         scanf("%d%d",&n,&m);
    48         for(int i=1;i<n;++i){
    49             int x,y,z;
    50             scanf("%d%d%d",&x,&y,&z);
    51             Add(x,y,z);Add(y,x,z);  //加边建树 
    52             sum[x]+=z;sum[y]+=z;   //统计相连且边权为1个数 
    53         }
    54         for(int i=1;i<=m;++i){
    55             int t;
    56             scanf("%d",&t);
    57             if(t){
    58                 int x,y,z;
    59                 scanf("%d%d%d",&x,&y,&z);
    60                 update(x,y,z);update(y,x,z);  //进行更新 
    61             }
    62             else work();
    63         }
    64     }
    65     return 0;
    66 }
    View Code
    
    
    

  • 相关阅读:
    分类问题的评价指标
    29 畅游 x86 分页机制(中)
    高手进阶,终极内存技术指南——完整/进阶版
    从ST官网获取STM32 AD封装库(包含原理图库和PCB库)详细教程
    标准SPI、DUAL SPI、Quad SPI;NorFlash、NandFlash、eMMC闪存的比较与区别
    ARM 之七 主流编译器(armcc、iar、gcc for arm)详细介绍
    STM32中ARM系列编译工具链的编译宏选择(__CC_ARM、__ICCARM__、__GNUC__、__TASKING__)
    每日总结
    每日总结
    每日总结
  • 原文地址:https://www.cnblogs.com/li-jia-hao/p/12690444.html
Copyright © 2020-2023  润新知