题解 Christmas Game
题目大意
给出 \(t\) 个 \(n\) 个点 \(m\) 条边的无向图,每次可以从任意一棵树选择一条边删掉,然后该树不与根(为 \(1\) )联通的部分被删掉。不能操作的人输。问谁有必胜策略。
每棵树都满足:每个环都只会挂在叶子节点上。
\(n\le 100,m\le 500\)
思路
怎么说呢?很厉害的题目吧。
首先考虑一个树的情况,我们设 \(sg(u)\) 表示 \(u\) 子树内的 \(sg\) 函数值,我们可以得到转移式:
\]
\]
这个可以通过打表发现,不过有一种比较巧妙的方法,就是说我们把主链拉出来,那么相当于每一个节点连了一条链,那么,删边就相当于取石子了。
然后考虑拓展到任意图上。这里给出一个结论:
一个环如果大小为偶数,它的顶点产生的贡献为 \(0\),反之为 \(1\)。
相当于环大小为偶数时,把环缩为一个点,否则再连向一个点。
考虑证明,我们发现我们可以通过枚举破掉环上哪条边来求,你发现环大小为偶数时,你破掉之后两条链长度一定一奇一偶,也就是对该环的根(挂的叶子)产生的贡献一定为偶数,所以第一个未出现的正整数一定为 \(1\)。同理,我们可以推出环大小为奇数的情况,这里就不再赘述了。
这里提醒一些细节:
需要考虑重边
需要考虑多个环串在一个顶点的情况
具体见代码就好了。
\(\texttt{Code1}\)
#include <cstdio>
#include <vector>
#include <cstring>
#include <bits/stdc++.h>
using namespace std;
#define Int register int
#define MAXN 105
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;}
template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}
int T,n,m,sg[MAXN],dep[MAXN],vis[MAXN];
int toop,head[MAXN],to[MAXN * 10],nxt[MAXN * 10];
void Add_Edge (int u,int v){
to[++ toop] = v,nxt[toop] = head[u],head[u] = toop;
to[++ toop] = u,nxt[toop] = head[v],head[v] = toop;
}
int dfs (int u,int fa){
bool flag = 0;
dep[u] = dep[fa] + 1,vis[u] = 1;
for (Int i = head[u];i;i = nxt[i]){
int v = to[i];
if (!v) continue;
if (v == fa && !flag){
flag = 1;
continue;
}
if (vis[v]){
sg[v] ^= (dep[u] - dep[v] + 1 & 1);
to[i ^ 1] = 0;
return v;
}
else{
int cur = dfs (v,u);
if (!cur) sg[u] ^= sg[v] + 1;
else if (cur ^ u) return cur;
}
}
return 0;
}
void clear (){
toop = 1,memset (head,0,sizeof (head));
for (Int i = 1;i <= n;++ i) sg[i] = dep[i] = vis[i] = 0;
}
signed main(){
while (~scanf ("%d",&T)){
int ans = 0;
while (T --> 0){
read (n),read (m),clear ();
for (Int i = 1,u,v;i <= m;++ i) read (u),read (v),Add_Edge (u,v);
dfs (1,0),ans ^= sg[1];
}
puts (ans ? "Sally" : "Harry");
}
return 0;
}
\(\texttt{Code2}\)
#include <cstdio>
#include <vector>
using namespace std;
#define Int register int
#define MAXN 105
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;}
template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}
vector <int> G[MAXN];
int T,n,m,top,sg[MAXN],dep[MAXN],vis[MAXN],sta[MAXN];
void Add_Edge (int u,int v){
G[u].push_back (v),
G[v].push_back (u);
}
void dfs (int u,int fa){
bool flag = 0;
sta[++ top] = u,vis[u] = 1;
for (Int i = 0;i < G[u].size();++ i){
int v = G[u][i];
if (v == fa && !flag){
flag = 1;
continue;
}
if (vis[v] == 1){
int cnt = 1;
while (sta[top] != v){
cnt ++;
vis[sta[top --]] = 0;
}
sg[v] ^= (cnt & 1);
}
else if (vis[v] == -1){
dfs (v,u);
if (vis[v]) sg[u] ^= sg[v] + 1;
}
}
if (vis[u]) -- top;
return ;
}
void clear (){
top = 0;
for (Int i = 1;i <= n;++ i) sg[i] = dep[i] = 0,vis[i] = -1,G[i].clear ();
}
signed main(){
while (~scanf ("%d",&T)){
int ans = 0;
while (T --> 0){
read (n),read (m),clear ();
for (Int i = 1,u,v;i <= m;++ i){
read (u),read (v);
if (u ^ v) Add_Edge (u,v);
}
dfs (1,0),ans ^= sg[1];
}
puts (ans ? "Sally" : "Harry");
}
return 0;
}
题解 Christmas Game的更多相关文章
- 题解 AT4278 【[ABC115A] Christmas Eve Eve Eve】
题目传送门. 分析 根据题目,我们可以发现要求如下: \(d\)的值 输出 \(d=25\) Christmas \(d=24\) Christmas Eve \(d=23\) Christmas E ...
- POJ3160 Father Christmas flymouse[强连通分量 缩点 DP]
Father Christmas flymouse Time Limit: 1000MS Memory Limit: 131072K Total Submissions: 3241 Accep ...
- poj 3013 Big Christmas Tree (最短路径Dijsktra) -- 第一次用优先队列写Dijsktra
http://poj.org/problem?id=3013 Big Christmas Tree Time Limit: 3000MS Memory Limit: 131072K Total S ...
- 【POJ3710】Christmas Game (博弈-树上的删边问题)
[题目] Description Harry and Sally were playing games at Christmas Eve. They drew some Christmas trees ...
- Codeforces:Good Bye 2018(题解)
Good Bye 2018! 题目链接:https://codeforces.com/contest/1091 A. New Year and the Christmas Ornament 题意: 给 ...
- AtCoder Beginner Contest 115 题解
题目链接:https://abc115.contest.atcoder.jp/ A Christmas Eve Eve Eve 题目: Time limit : 2sec / Memory limit ...
- Good Bye 2018题解
Good Bye 2018题解 题解 CF1091A [New Year and the Christmas Ornament] 打完cf都忘记写题解了qwq 题意就是:给你一些黄,蓝,红的球,满足蓝 ...
- Codeforces Round #611 (Div. 3) A-F简要题解
contest链接:https://codeforces.com/contest/1283 A. Minutes Before the New Year 题意:给一个当前时间,输出离第二天差多少分钟 ...
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
随机推荐
- springboot中redis取缓存类型转换异常
异常如下: [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested ...
- mysql8.0----mysqldump抛出:Unknown table 'COLUMN_STATISTICS' in information_schema (1109)
问题:我尝试使用mysqldump时,得到以下错误: 复制 $> mysqldump --single-transaction --h -u user -p db > db.sql my ...
- seo高手教你seo优化排名该怎么做
seo高手教你seo优化排名该怎么做 第一节:如何在本地搭建服务器环境 本节课程主要是讲如何利用 Xampp在本地搭建服务器环境 .网站使用asp和php比较常见,当然,就目前而言,使用php搭建网站 ...
- centos7 权限更改,所属用户及用户组更改
2021-08-03 # 查看文件的权限 ll 第一个字符, "-" 表示是文件, "d" 表示是目录(directory) 后面 9 个字符每 3 个字符又作 ...
- RabbitMQ-初见
目录 什么是中间件 消息队列协议 AMQP协议 MQTT协议 OpenMessage协议 Kafka协议 消息队列持久化 消息的分发策略 消息队列高可用和高可靠 什么是高可用机制 集群模式1 - Ma ...
- 如何实现LRU缓存?
面试官:来了,老弟,LRU缓存实现一下? 我:直接LinkedHashMap就好了. 面试官:不要用现有的实现,自己实现一个. 我:..... 面试官:回去等消息吧.... 大家好,我是程序员学长,今 ...
- JMeter中使用交替控制器设置循环次数后都执行一次?
JMeter在线程组设置循环3次,执行后只执行了一次就停止执行了 排查原因:线程组下添加了一些请求信息(HTTP Cache Manager.HTTP Cookie Manager.HTTP Requ ...
- Docker 面试宝典
Docker 是什么? 是实现容器技术的一种工具 是一个开源的应用容器引擎 使用 C/S 架构模式,通过远程API 来管理 可以打包一个应用及依赖包到一个轻量级.可移植的容器中 容器是什么? 对应用软 ...
- RabbitMQ核心知识总结!
本文已经收录到github仓库,此仓库用于分享Java相关知识总结,包括Java基础.MySQL.Spring Boot.MyBatis.Redis.RabbitMQ.计算机网络.数据结构与算法等等, ...
- 谈谈Linux系统启动流程
@ 目录 大体流程分析 一.BIOS 1.1 BIOS简介 1.2 POST 二.BootLoader (GRUB) 2.1 What's MBR? 2.2 What's GRUB? 2.3 boot ...