题目传送门

题目大意

给出 \(t\) 个 \(n\) 个点 \(m\) 条边的无向图,每次可以从任意一棵树选择一条边删掉,然后该树不与根(为 \(1\) )联通的部分被删掉。不能操作的人输。问谁有必胜策略。

每棵树都满足:每个环都只会挂在叶子节点上。

\(n\le 100,m\le 500\)

思路

怎么说呢?很厉害的题目吧。

首先考虑一个树的情况,我们设 \(sg(u)\) 表示 \(u\) 子树内的 \(sg\) 函数值,我们可以得到转移式:

\[sg(u)=\text{mex}_{v\in son_u}\{sg(v)\}
\]
\[\Rightarrow sg(u)=\otimes_{v\in son_u} (sg(v)+1)
\]

这个可以通过打表发现,不过有一种比较巧妙的方法,就是说我们把主链拉出来,那么相当于每一个节点连了一条链,那么,删边就相当于取石子了。

然后考虑拓展到任意图上。这里给出一个结论:

一个环如果大小为偶数,它的顶点产生的贡献为 \(0\),反之为 \(1\)。

相当于环大小为偶数时,把环缩为一个点,否则再连向一个点。

考虑证明,我们发现我们可以通过枚举破掉环上哪条边来求,你发现环大小为偶数时,你破掉之后两条链长度一定一奇一偶,也就是对该环的根(挂的叶子)产生的贡献一定为偶数,所以第一个未出现的正整数一定为 \(1\)。同理,我们可以推出环大小为奇数的情况,这里就不再赘述了。

这里提醒一些细节:

  • 需要考虑重边

  • 需要考虑多个环串在一个顶点的情况

具体见代码就好了。

\(\texttt{Code1}\)

  1. #include <cstdio>
  2. #include <vector>
  3. #include <cstring>
  4. #include <bits/stdc++.h>
  5. using namespace std;
  6. #define Int register int
  7. #define MAXN 105
  8. template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
  9. template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}
  10. int T,n,m,sg[MAXN],dep[MAXN],vis[MAXN];
  11. int toop,head[MAXN],to[MAXN * 10],nxt[MAXN * 10];
  12. void Add_Edge (int u,int v){
  13. to[++ toop] = v,nxt[toop] = head[u],head[u] = toop;
  14. to[++ toop] = u,nxt[toop] = head[v],head[v] = toop;
  15. }
  16. int dfs (int u,int fa){
  17. bool flag = 0;
  18. dep[u] = dep[fa] + 1,vis[u] = 1;
  19. for (Int i = head[u];i;i = nxt[i]){
  20. int v = to[i];
  21. if (!v) continue;
  22. if (v == fa && !flag){
  23. flag = 1;
  24. continue;
  25. }
  26. if (vis[v]){
  27. sg[v] ^= (dep[u] - dep[v] + 1 & 1);
  28. to[i ^ 1] = 0;
  29. return v;
  30. }
  31. else{
  32. int cur = dfs (v,u);
  33. if (!cur) sg[u] ^= sg[v] + 1;
  34. else if (cur ^ u) return cur;
  35. }
  36. }
  37. return 0;
  38. }
  39. void clear (){
  40. toop = 1,memset (head,0,sizeof (head));
  41. for (Int i = 1;i <= n;++ i) sg[i] = dep[i] = vis[i] = 0;
  42. }
  43. signed main(){
  44. while (~scanf ("%d",&T)){
  45. int ans = 0;
  46. while (T --> 0){
  47. read (n),read (m),clear ();
  48. for (Int i = 1,u,v;i <= m;++ i) read (u),read (v),Add_Edge (u,v);
  49. dfs (1,0),ans ^= sg[1];
  50. }
  51. puts (ans ? "Sally" : "Harry");
  52. }
  53. return 0;
  54. }

\(\texttt{Code2}\)

  1. #include <cstdio>
  2. #include <vector>
  3. using namespace std;
  4. #define Int register int
  5. #define MAXN 105
  6. template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
  7. template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}
  8. vector <int> G[MAXN];
  9. int T,n,m,top,sg[MAXN],dep[MAXN],vis[MAXN],sta[MAXN];
  10. void Add_Edge (int u,int v){
  11. G[u].push_back (v),
  12. G[v].push_back (u);
  13. }
  14. void dfs (int u,int fa){
  15. bool flag = 0;
  16. sta[++ top] = u,vis[u] = 1;
  17. for (Int i = 0;i < G[u].size();++ i){
  18. int v = G[u][i];
  19. if (v == fa && !flag){
  20. flag = 1;
  21. continue;
  22. }
  23. if (vis[v] == 1){
  24. int cnt = 1;
  25. while (sta[top] != v){
  26. cnt ++;
  27. vis[sta[top --]] = 0;
  28. }
  29. sg[v] ^= (cnt & 1);
  30. }
  31. else if (vis[v] == -1){
  32. dfs (v,u);
  33. if (vis[v]) sg[u] ^= sg[v] + 1;
  34. }
  35. }
  36. if (vis[u]) -- top;
  37. return ;
  38. }
  39. void clear (){
  40. top = 0;
  41. for (Int i = 1;i <= n;++ i) sg[i] = dep[i] = 0,vis[i] = -1,G[i].clear ();
  42. }
  43. signed main(){
  44. while (~scanf ("%d",&T)){
  45. int ans = 0;
  46. while (T --> 0){
  47. read (n),read (m),clear ();
  48. for (Int i = 1,u,v;i <= m;++ i){
  49. read (u),read (v);
  50. if (u ^ v) Add_Edge (u,v);
  51. }
  52. dfs (1,0),ans ^= sg[1];
  53. }
  54. puts (ans ? "Sally" : "Harry");
  55. }
  56. return 0;
  57. }

题解 Christmas Game的更多相关文章

  1. 题解 AT4278 【[ABC115A] Christmas Eve Eve Eve】

    题目传送门. 分析 根据题目,我们可以发现要求如下: \(d\)的值 输出 \(d=25\) Christmas \(d=24\) Christmas Eve \(d=23\) Christmas E ...

  2. POJ3160 Father Christmas flymouse[强连通分量 缩点 DP]

    Father Christmas flymouse Time Limit: 1000MS   Memory Limit: 131072K Total Submissions: 3241   Accep ...

  3. poj 3013 Big Christmas Tree (最短路径Dijsktra) -- 第一次用优先队列写Dijsktra

    http://poj.org/problem?id=3013 Big Christmas Tree Time Limit: 3000MS   Memory Limit: 131072K Total S ...

  4. 【POJ3710】Christmas Game (博弈-树上的删边问题)

    [题目] Description Harry and Sally were playing games at Christmas Eve. They drew some Christmas trees ...

  5. Codeforces:Good Bye 2018(题解)

    Good Bye 2018! 题目链接:https://codeforces.com/contest/1091 A. New Year and the Christmas Ornament 题意: 给 ...

  6. AtCoder Beginner Contest 115 题解

    题目链接:https://abc115.contest.atcoder.jp/ A Christmas Eve Eve Eve 题目: Time limit : 2sec / Memory limit ...

  7. Good Bye 2018题解

    Good Bye 2018题解 题解 CF1091A [New Year and the Christmas Ornament] 打完cf都忘记写题解了qwq 题意就是:给你一些黄,蓝,红的球,满足蓝 ...

  8. Codeforces Round #611 (Div. 3) A-F简要题解

    contest链接:https://codeforces.com/contest/1283 A. Minutes Before the New Year 题意:给一个当前时间,输出离第二天差多少分钟 ...

  9. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

随机推荐

  1. jdbc操作mysql(四):利用反射封装

    前言 有了前面利用注解拼接sql语句,下面来看一下利用反射获取类的属性和方法 不过好像有一个问题,数据库中的表名和字段中带有下划线该如何解决呢 实践操作 工具类:获取connection对象 publ ...

  2. 小程序跨页面传递data数据的三种方法

    Q:小程序怎么把页面data里的数据传到另外的页面? 或者小程序怎么吧表单里的数据传到另外的页面?A:1.可以使用url传递数据. 例如在A页面中传递数据,需要注意的是,wx.switchTab中的u ...

  3. shell脚本书写

    #!/bin/bash #指定脚本默认使用的命令解释器 第1行 幻数 #!/usr/bin/python #!/bin/awk #!/bin/sed

  4. Java 字符串格式化和工具类使用

    前言 我们在做项目时候经常需要对字符串进行处理,判断,操作,所以我就总结了一下java 字符串一些常用操作,和推荐比较好用我在自用的工具类,毕竟有轮子我们自己就不用重复去写了,提供开发效率,剩下的时间 ...

  5. 被面试官问懵:TCP 四次挥手收到乱序的 FIN 包会如何处理?

    摘要:收到个读者的问题,他在面试的时候,被搞懵了,因为面试官问了他这么一个网络问题. 本文分享自华为云社区<TCP 四次挥手收到乱序的 FIN 包会如何处理?>,作者:小林coding . ...

  6. Flask - 访问返回字典的接口报错:The view function did not return a valid response. The return type must be a string, tuple, Response instance, or WSGI callable, but it was a dict.

    背景 有一个 Flask 项目,然后有一个路由返回的是 dict 通过浏览器访问,结果报错 关键报错信息 TypeError: 'dict' object is not callable The vi ...

  7. Jenkins(8)- CentOS 7.x 通过yum安装jenkins

    如果想从头学起Jenkins的话,可以看看这一系列的文章哦 https://www.cnblogs.com/poloyy/category/1645399.html 下载rpm包 sudo wget ...

  8. ElasticAlert基于聚合告警

    背景 最近公司网站经常被漏洞扫描,虽然并没有什么漏洞给对方利用,但是每次扫描我们也必须要察觉到,如果扫描的量太大,可以考虑从公有云的安全组上禁用掉这个IP,所以需要统计指定时间内每个IP的访问次数,这 ...

  9. Spring事务管理回滚问题

    Spring事务管理不能回滚问题 在前段时间学习SpringMVC的练习中,碰到声明式事务管理时,事务不能回滚的情况,通过查看博客和资料,解决了问题. 原因 导致Spring事务管理不能回滚的原因有两 ...

  10. [第九篇]——Docker 镜像使用之Spring Cloud直播商城 b2b2c电子商务技术总结

    Docker 镜像使用 当运行容器时,使用的镜像如果在本地中不存在,docker 就会自动从 docker 镜像仓库中下载,默认是从 Docker Hub 公共镜像源下载. 下面我们来学习: 1.管理 ...