题解 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. 树链剖分数据结构板题 题目大意:我 ...
随机推荐
- 高德地图——骑行路线&骑行指定
&plugin=AMap.Riding 也是[]中放json, 包含keyword和city,不能有途经1.骑行路线(关键字) <!DOCTYPE html> <html&g ...
- 发布 mbtiles 存储的矢量瓦片
之前我们分享过如何 在本地发布OSM矢量瓦片地图,里面介绍了生成的矢量瓦片会存放在 .mbtiles 文件中,然后用 tileserver-gl 软件发布. mbtiles 是基于sqllite数据库 ...
- Ansible基础使用
原文转自:https://www.cnblogs.com/itzgr/p/10233932.html作者:木二 目录 一 Ansible命令用法 1.1 免密钥 1.2 Ad-Hoc基础命令 1.3 ...
- Java中Scanner用法总结
最近在做OJ类问题的时候,经常由于Scanner的使用造成一些细节问题导致程序不通过(最惨的就是网易笔试,由于sc死循环了也没发现,导致AC代码也不能通过...),因此对Scanner进行了一些总结整 ...
- 「山东省队集训2021 Round 1」 半夜
考虑将 \(X\) 复制一次放到后面再对其长度为 \(n\) 的连续子串和 \(Y\) 求一波 \(\rm{Longest\ Common\ Subsequence}\) 就能得到 \(\Theta( ...
- 面试HashMap你都扛不住,还想拿到offer?
当我们面试Java开发岗位时,面试官问的频率出现最多的问题,就是这个HashMap,不管是传统型公司还是互联公司,HashMap是必问的,所以作者爆肝整理了HashMap的23个问题以及答案,请查收! ...
- 【第六篇】- Maven 仓库之Spring Cloud直播商城 b2b2c电子商务技术总结
Maven 仓库 在 Maven 的术语中,仓库是一个位置(place). Maven 仓库是项目中依赖的第三方库,这个库所在的位置叫做仓库. 在 Maven 中,任何一个依赖.插件或者项目构建的输出 ...
- .net Core 基于EF Core 实现数据库上下文
在做项目时,需要将某一些功能的实体建立在另一个数据库中,连接不同的数据库用以存储记录.通过查找资料,实现EF Core上下文. 下面是实现上下文后的解决方案的目录: 1.UpAndDownDbCont ...
- 迷宫3---BFS
经过思考蒜头君终于解决了怎么计算一个迷宫的最短路问题,于是蒜头君找到一个新的迷宫图,来验证自己是否真的会计算一个迷宫的最短路. 为了检验自己计算的是否正确,蒜头君特邀你一起来计算. 输入格式 第一行输 ...
- vue注意点
template下面只能有一个节点,不能是多个