题目链接

题目描述

「UniversalNO」的规则如下:每张牌有一种颜色和一个点数。两个人轮流出牌,由 Alice 先手,最开始牌堆为空,出的人可以出任意牌(放到牌堆顶),之后出的牌必须和当时牌堆顶的牌的颜色或点数至少有一个相同。有牌可出者必须出,无牌可出者输。

Alice 和 Shinobu 玩了几局后觉得原来的规则太依靠运气,于是她们加了一个新玩法:Alice 出了第一张之后,两个人立即交换手里的牌,然后从 Alice 开始继续按原来的规则进行游戏。当然,这次 Alice 出的牌必须和她刚开始出的颜色或点数至少有一个相同。

交换之后两人都知道对方的手牌(就是开局时自己的手牌),于是就有必胜策略了。

现在已知 Alice 和 Shinobu 手里一开始的牌,请你求出对于 Alice 第一次出牌的每种情况,谁有必胜策略。

Sol

不难看出出了一张牌后另一个人能够出的牌是可以事先知道的。

那么这就形成一个二分图。

博弈过程相当于是一开始在先手的点上放了一个棋子,然后每次轮流沿着出边走,不能走的人失败。

这是一个经典的二分图博弈模型

先手必胜当且仅当棋子所在点一定在最大匹配中。

判断方法:

跑网络流,要求源点到这个点有流量且这个点没有被分割在源点集合。

code:

#include<bits/stdc++.h>
using namespace std;
#define Set(a,b) memset(a,b,sizeof(a))
template<class T>inline void init(T&x){
x=0;char ch=getchar();bool t=0;
for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') t=1;
for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+(ch-48);
if(t) x=-x;return;
}typedef long long ll;
const int N=4e4+10;
const int MAXN=2e5+10;
const int MAXM=2e6+10;
int m,c,n1,n2;
struct edge{
int to,next,cap;
}a[MAXM<<2];
int head[MAXN],cnt=0,cur[MAXN],d[MAXN];
inline void add(int x,int y,int z){a[cnt]=(edge){y,head[x],z};head[x]=cnt++;}
inline void add_edge(int x,int y,int z){add(x,y,z),add(y,x,0);}
int X1[N],X2[N],Y1[N],Y2[N];
int idnum[N],idcol[N],idshi[N];
int S=0,T;
queue<int> Q;
int dfs(int u,int flow){
if(u==T) return flow;
int res=flow;
for(int v,&i=cur[u];~i;i=a[i].next) {
v=a[i].to;if(!a[i].cap||d[v]!=d[u]+1) continue;
int f=dfs(v,min(res,a[i].cap));
a[i].cap-=f,a[i^1].cap+=f;
res-=f;if(!f) d[v]=0;
if(!res) break;
}
return flow-res;
}
inline bool bfs(){
for(int i=S;i<=T;++i) d[i]=0;d[S]=1;
while(!Q.empty()) Q.pop();Q.push(S);
while(!Q.empty()) {
int u=Q.front();Q.pop();
for(int v,i=head[u];~i;i=a[i].next) {
v=a[i].to;if(!a[i].cap||d[v]) continue;
d[v]=d[u]+1;if(v==T) return 1;Q.push(v);
}
}
return d[T];
}
inline void Dinic(){
int fl=0;
while(bfs()) memcpy(cur,head,sizeof(cur)),fl+=dfs(S,1e9);
return;
}
int ans[N];
int main()
{
init(m),init(c);init(n1);
Set(head,-1);for(int i=1;i<=n1;++i) init(X1[i]),init(Y1[i]);
init(n2);int h=n1;
for(int i=1;i<=n2;++i) idshi[i]=++h;
for(int i=1;i<=m;++i) idnum[i]=++h;
for(int i=1;i<=c;++i) idcol[i]=++h;
T=++h;
for(int i=1;i<=n1;++i) add_edge(S,i,1),add_edge(i,idnum[X1[i]],1),add_edge(i,idcol[Y1[i]],1);
for(int i=1;i<=n2;++i) init(X2[i]),init(Y2[i]),add_edge(idshi[i],T,1),add_edge(idnum[X2[i]],idshi[i],1),add_edge(idcol[Y2[i]],idshi[i],1);
Dinic();bfs();
for(int v,i=head[S];~i;i=a[i].next) {v=a[i].to;if(v>0&&v<=n1&&!a[i].cap&&!d[v]) ans[v]=1;}
for(int i=1;i<=n1;++i) puts(ans[i]? "1":"0");
return 0;
}

【LOJ#536】「LibreOJ Round #6」花札的更多相关文章

  1. loj536「LibreOJ Round #6」花札(二分图博弈)

    loj536「LibreOJ Round #6」花札(二分图博弈) loj 题解时间 很明显是二分图博弈. 以某个点为起点,先手必胜的充要条件是起点一定在最大匹配中. 判断方法是看起点到该点的边有流量 ...

  2. loj536 「LibreOJ Round #6」花札

    一眼二分图博弈,于是我们可以拿到69分的好成绩. 二分图暴力加边的数目是O(n^2)的,于是我们考虑网络流优化建图,将alice的每个牌向其的颜色和编号节点连边,bob的每个牌由其颜色和编号节点向其连 ...

  3. [LOJ#531]「LibreOJ β Round #5」游戏

    [LOJ#531]「LibreOJ β Round #5」游戏 试题描述 LCR 三分钟就解决了问题,她自信地输入了结果-- > -- 正在检查程序 -- > -- 检查通过,正在评估智商 ...

  4. [LOJ#530]「LibreOJ β Round #5」最小倍数

    [LOJ#530]「LibreOJ β Round #5」最小倍数 试题描述 第二天,LCR 终于启动了备份存储器,准备上传数据时,却没有找到熟悉的文件资源,取而代之的是而屏幕上显示的一段话: 您的文 ...

  5. [LOJ#516]「LibreOJ β Round #2」DP 一般看规律

    [LOJ#516]「LibreOJ β Round #2」DP 一般看规律 试题描述 给定一个长度为 \(n\) 的序列 \(a\),一共有 \(m\) 个操作. 每次操作的内容为:给定 \(x,y\ ...

  6. [LOJ#515]「LibreOJ β Round #2」贪心只能过样例

    [LOJ#515]「LibreOJ β Round #2」贪心只能过样例 试题描述 一共有 \(n\) 个数,第 \(i\) 个数 \(x_i\) 可以取 \([a_i , b_i]\) 中任意值. ...

  7. [LOJ#525]「LibreOJ β Round #4」多项式

    [LOJ#525]「LibreOJ β Round #4」多项式 试题描述 给定一个正整数 k,你需要寻找一个系数均为 0 到 k−1 之间的非零多项式 f(x),满足对于任意整数 x 均有 f(x) ...

  8. [LOJ#526]「LibreOJ β Round #4」子集

    [LOJ#526]「LibreOJ β Round #4」子集 试题描述 qmqmqm有一个长为 n 的数列 a1,a2,……,an,你需要选择集合{1,2,……,n}的一个子集,使得这个子集中任意两 ...

  9. [LOJ#522]「LibreOJ β Round #3」绯色 IOI(危机)

    [LOJ#522]「LibreOJ β Round #3」绯色 IOI(危机) 试题描述 IOI 的比赛开始了.Jsp 和 Rlc 坐在一个角落,这时他们听到了一个异样的声音 …… 接着他们发现自己收 ...

随机推荐

  1. VS2008编译boost1.53

    1. 准备工作:下载boost_1_53_0.zip(bzip2-1.0.6.tar.gz/icu4c-4_4_2-Win32-msvc9.zip/Python-2.5.2.tar.bz2/zlib- ...

  2. python 爬虫 基于requests模块发起ajax的get请求

    基于requests模块发起ajax的get请求 需求:爬取豆瓣电影分类排行榜 https://movie.douban.com/中的电影详情数据 用抓包工具捉取 使用ajax加载页面的请求 鼠标往下 ...

  3. NXP-PN511-antenna-design-quide

    NXP-PN511-antenna-design-quide  文库有下载 C1 C2

  4. [python] 正则表达式细节

    1.零宽断言 所谓零宽断言就是并不去真正的匹配字符串文本,而仅仅是匹配对应的位置. 正则表达式中有很多这样的断言,常见的如匹配字符串或者行的起始位置 ^ 和 /A,匹配字符串或者行的末尾 $ 和 /Z ...

  5. 【扩展GCD】荒岛野人

    题目 [题目描述] 克里特岛以野人群居而著称.岛上有排列成环行的M个山洞.这些山洞顺时针编号为1,2,-,M.岛上住着N个野人,一开始依次住在山洞C1,C2,-,CN中,以后每年,第i个野人会沿顺时针 ...

  6. python网络编程——使用UDP、TCP协议收发信息

    UDP UDP是面向无连接的通讯协议,UDP数据包括目的端口号和源端口号信息,由于通讯不需要连接,所以可以实现广播发送. UDP传输数据时有大小限制,每个被传输的数据报必须限定在64KB之内. UDP ...

  7. SpringBoot中使用Websocket进行消息推送

    WebsocketConfig.java @Configuration public class WebSocketConfig { @Bean public ServerEndpointExport ...

  8. 关于Android studio调用高德地图的简单流程和要点

    一,账号与Key的申请 注册成为高德开发者需要分三步: 第一步,注册高德开发者:第二步,去控制台创建应用:第三步,获取Key. 前2步都比较简单,这里说下第三步. 获取Key 1.进入控制台,创建一个 ...

  9. vue开大主要难点解决方式

    问题:在我们那vue开发项目时,多层嵌套组件最繁琐,组件传参成最难的问题,并且对兄弟组件传参也无能为力,也会导致代码很难维护. 解决:采用vuex状态管理,把所有的事件和状态都储存在store对象中, ...

  10. php后门简单检测脚本

    # coding:utf-8 import os import sys import re rulelist = [ '(\$_(GET|POST|REQUEST)\[.{0,15}\]\(\$_(G ...