【ZOJ3316】Game(带花树)
【ZOJ3316】Game(带花树)
题面
Vjudge
翻译:
给定棋盘上\(n\)个旗子
一开始先手可以随便拿,
然后每次都不能取离上次的曼哈顿距离超过\(L\)的旗子
谁不能动谁输。
问后手能否赢?
题解
假的博弈论
对于所有曼哈顿距离小于等于\(L\)的点连边
检查是否存在完美匹配
如果存在完美匹配,每次先手选择一个点,后手只需要选择对应的点即可。
否则一定存在一个无法匹配的点,与它曼哈顿距离小于等于\(L\)的个数一定是偶数个(如果是奇数个就会与它匹配)
那么这个联通块的大小是奇数个,后手必败。(假的证明)
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define MAX 362
inline int read()
{
RG int x=0,t=1;RG char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
struct Line{int v,next;}e[MAX*MAX];
int h[MAX],cnt=1;
inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;}
int dfn[MAX],tim;
int f[MAX],n;
int pre[MAX],vis[MAX],match[MAX];
int getf(int x){return x==f[x]?x:f[x]=getf(f[x]);}
int lca(int u,int v)
{
++tim;u=getf(u),v=getf(v);
while(dfn[u]!=tim)
{
dfn[u]=tim;
u=getf(pre[match[u]]);
if(v)swap(u,v);
}
return u;
}
queue<int> Q;
void blossom(int x,int y,int w)
{
while(getf(x)!=w)
{
pre[x]=y;y=match[x];
if(vis[y]==2)vis[y]=1,Q.push(y);
if(f[x]==x)f[x]=w;
if(f[y]==y)f[y]=w;
x=pre[y];
}
}
bool Aug(int S)
{
for(int i=1;i<=n;++i)f[i]=i,vis[i]=pre[i]=0;
while(!Q.empty())Q.pop();Q.push(S);vis[S]=1;
while(!Q.empty())
{
int u=Q.front();Q.pop();
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;
if(getf(u)==getf(v)||vis[v]==2)continue;
if(!vis[v])
{
vis[v]=2;pre[v]=u;
if(!match[v])
{
for(int x=v,lst;x;x=lst)
lst=match[pre[x]],match[x]=pre[x],match[pre[x]]=x;
return true;
}
vis[match[v]]=1;Q.push(match[v]);
}
else
{
int w=lca(u,v);
blossom(u,v,w);blossom(v,u,w);
}
}
}
return false;
}
void init()
{
memset(h,0,sizeof(h));cnt=1;
memset(match,0,sizeof(match));
}
int X[MAX],Y[MAX],L;
int main()
{
while(scanf("%d",&n)!=EOF)
{
init();
for(int i=1;i<=n;++i)X[i]=read(),Y[i]=read();
L=read();int ans=0;
if(n&1){puts("NO");continue;}
for(int i=1;i<=n;++i)
for(int j=i+1;j<=n;++j)
if(abs(X[i]-X[j])+abs(Y[i]-Y[j])<=L)
Add(i,j),Add(j,i);
for(int i=1;i<=n;++i)if(!match[i])ans+=Aug(i);
(ans==n/2)?puts("YES"):puts("NO");
}
return 0;
}
【ZOJ3316】Game(带花树)的更多相关文章
- [转]带花树,Edmonds's matching algorithm,一般图最大匹配
看了两篇博客,觉得写得不错,便收藏之.. 首先是第一篇,转自某Final牛 带花树……其实这个算法很容易理解,但是实现起来非常奇葩(至少对我而言). 除了wiki和amber的程序我找到的资料看着都不 ...
- HDOJ 4687 Boke and Tsukkomi 一般图最大匹配带花树+暴力
一般图最大匹配带花树+暴力: 先算最大匹配 C1 在枚举每一条边,去掉和这条边两个端点有关的边.....再跑Edmonds得到匹配C2 假设C2+2==C1则这条边再某个最大匹配中 Boke and ...
- 【Learning】带花树——一般图最大匹配
一般图最大匹配--带花树 问题 给定一个图,求该图的最大匹配.即找到最多的边,使得每个点至多属于一条边. 这个问题的退化版本就是二分图最大匹配. 由于二分图中不存在奇环,偶环对最大匹配并无 ...
- 【learning】一般图最大匹配——带花树
问题描述 对于一个图\(G(V,E)\),当点对集\(S\)满足任意\((u,v)\in S\),均有\(u,v\in V,(u,v)\in E\),且\(S\)中没有点重复出现,我们称\(S\) ...
- [BZOJ]4405: [wc2016]挑战NPC(带花树)
带花树模板 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; ...
- 【XSY2774】学习 带花树
题目描述 给你一个图,求最大匹配. 边的描述方式很特殊,就是一次告诉你\(c_i\)个点:\(d_1,d_2,\ldots,d_{c_i}\),表示这些点两两之间都有连边,也就是说,这是一个团.总共有 ...
- HDU 4687 Boke and Tsukkomi (一般图最大匹配)【带花树】
<题目链接> 题目大意: 给你n个点和m条边,每条边代表两点具有匹配关系,问你有多少对匹配是冗余的. 解题分析: 所谓不冗余,自然就是这对匹配关系处于最大匹配中,即该匹配关系有意义.那怎样 ...
- URAL 1099 Work Scheduling (一般图最大匹配) 模板题【带花树】
<题目链接> <转载于 >>> > 题目大意: 给出n个士兵,再给出多组士兵之间两两可以匹配的关系.已知某个士兵最多只能与一个士兵匹配.求最多能够有多少对匹 ...
- BZOJ 4405 [wc2016]挑战NPC 带花树 一般图最大匹配
https://www.lydsy.com/JudgeOnline/problem.php?id=4405 这道题大概就是考场上想不出来,想出来也调不出来的题. 把每个桶拆成三个互相有边的点,每个球向 ...
随机推荐
- vscode eslint格式化配置
{ // vscode默认启用了根据文件类型自动设置tabsize的选项 "editor.detectIndentation": false, // 重新设定tabsize &qu ...
- JMeter自学笔记1-环境安装
一.写在前面的话: Jmeter是一款优秀的开源测试工具, 是每位测试工程师进阶过程中,需要熟悉并掌握的一款测试工具,熟练使用Jmeter能大大提高工作效率. Jmeter环境安装需要依赖JDK,所以 ...
- TPO 02 - Early Cinema
TPO 02 - Early Cinema NOTE: 主要意思(大概就是主谓宾)用粗体标出:重要的其它用斜体: []中的是大致意思,可能与原文有关也可能无关,但不会离题 目的为训练句子/段落总结能力 ...
- 4星|《亿万》:FBI大战华尔街对冲基金大鳄
亿万:围剿华尔街大白鲨 全书尝试还原2008-2013年前后FBI指控赛克资本老板科恩通过内幕交易盈利的案件细节. 作者花了数年时间,采访了200多位当事人,阅读了海量的相关资料.书中交代了科恩的发家 ...
- 【坚持】Selenium+Python学习之从读懂代码开始 DAY3
2018/05/15 [来源:菜鸟教程](http://www.runoob.com/python3/python3-examples.html) #No.1 list = [1, 2, 3, 4] ...
- JAVA学习笔记--迭代器
迭代器(Iterator)是一种设计模式.它是一个对象,它的工作是遍历并选择序列中的对象,而客户端程序员不必知道或关心该序列底层的结构.创建迭代器的代价小,因而迭代器通常被称为轻量级对象. 一.Ite ...
- SPP-net论文总结
SPPNet方法来自<Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition> ,是大神 ...
- [咸恩静][Coffee House]
歌词来源:http://music.163.com/#/song?id=5400159 하루의 시작은 향긋한 커피 [ha-lu-e xi-ja-geun hyang-geu-Tan Keo-Pi] ...
- Django 使用 Celery 实现异步任务
对于网站来说,给用户一个较好的体验是很重要的事情,其中最重要的指标就是网站的浏览速度.因此服务端要从各个方面对网站性能进行优化,比如可采用CDN加载一些公共静态文件,如js和css:合并css或者js ...
- 每天一个linux命令集
linux命令汇总,装载来自: http://www.cnblogs.com/peida/category/309012.html