• 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!
    ");
    69                 else printf("Boys win!
    ");
    70             }
    71         }
    72     }
    73     return 0;
    74 }
  • 相关阅读:
    linux一些配置
    tomcat启动后,页面无法访问
    利用jmeter实现多IP压测
    java操作数据库
    excle中表头分割单元格
    常用的最大流算法 Dinic 和 最小费用最大流SPFA写法
    [kuangbin]带你飞之'网络流'专题
    (留坑以后再看)一般图'最大匹配' 带花树 算法
    二分图'多重匹配'
    二分图'最大匹配' HK 算法
  • 原文地址:https://www.cnblogs.com/zarth/p/6719406.html
Copyright © 2020-2023  润新知