二分图博弈(知识总结+例题)

news2024/11/17 13:27:34

思路来源

gzchenben的ppt

算法学习笔记(74): 二分图博弈 - 知乎

https://www.cnblogs.com/Zeardoe/p/16534557.html

知识点总结

以下部分摘自知乎:算法学习笔记(74): 二分图博弈 - 知乎

二分图博弈模型

给出一张二分图起始点 H ,

A和B轮流操作,每次只能选与上个被选择的点(第一回合则是点 H )相邻的点,

且不能选择已选择过的点,无法选点的人输掉。

例如,在国际象棋棋盘上,双方轮流移动一个士兵,

不能走已经走过的格子,问谁先无路可走。

结论

考察二分图的最大匹配,如果最大匹配一定包含 H ,那么先手必胜,否则先手必败。

1. 如果最大匹配一定包含 H,那么先手只需要一直按照匹配选点即可。

后手不可能选到非匹配点:

反证法,设如果后手选到一个非匹配点,

设路径为 H→P1→⋯→Pn−1→Pn ,

那么把现在的匹配 {H−P1,…,Pn−2−Pn−1} 换成{P1−P2,…,Pn−1−Pn},

匹配数不变但不包含 H ,与最大匹配一定包含 H 矛盾。

2. 如果最大匹配不一定包含 H ,考虑某个不包含 H 的最大匹配 M 。

先手无论选择哪个点,它都一定是匹配点,

否则设这个点为 P ,则发现了新匹配 H−P ,与 M 是最大匹配矛盾。

之后后手一直按照匹配选点即可,先手不可能选到非匹配点,此时局面和1相同

方法论

我们可以对删除和不删除 H 的情形分别做二分图最大匹配,

如果删除两个匹配数一样多,说明 H 是可有可无的,存在不包含 H 的最大匹配。

否则,说明 H 是不可或缺的。

具体实现可以根据数据范围选用匈牙利算法Dinic

需要注意的是,如果采用Dinic,不要根据有没有 H 点建两次图。

而是在建图时把涉及 H 点的边存下来,

跑完第一次Dinic后再建这些边,第二次Dinic看有没有增加流量。

实际操作的时候,

若H位于二分图左半侧,只需令超级源点S->H边在第二轮连

若H位于二分图右半侧,令H->超级汇点T的边在第二轮连即可

二分图上包含H的边,还是可以在第一轮匹配的时候先连好

因为只要那一条边不连,H对流量就无贡献,

根据网络流的最优性质,答案会优先占用可以贡献流量的点

题目

其实也想不到除了用裸题考以外,还能有什么考查方式,因为知识点比较固定

2020 China Collegiate Programming Contest Changchun Onsite H题,二分图博弈裸题

t(t<=10)组样例,m(m<=5)位循环密码锁,

密码锁每一位0-9(9和0循环相邻),

每一次拨动可以使i拨到(i-1)%10或(i+1)%10的位置

初始密码为x,Alice和Bob需要轮流拨动,

n(0<=n<10^m)个禁止密码,只要一拨到禁止密码就输了,保证x不在里面

Alice先手,不能操作者输,问双方均最优解下谁必胜

题解

考虑密码各数位和的奇偶性,显然是一个二分图

1. 先不加x的边,跑一次dinic

2. 再把x加上,在残余网络上再跑一次dinic

x是必须点,当且仅当第二次dinic时,流量为1

由于连边时,控制了x一定位于二分图左半端,

所以,第二轮加上边的时候,只加S->x即可

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10,maxm=3e6+10,INF=0x3f3f3f3f;
int level[maxn];
int head[maxn],cnt;
int ca,n,m,ss,ee,ten[10],st,sum[maxn];
bool ban[maxn];
struct edge{int v,nex;ll w;}e[maxm];
void init(){
	cnt=0;
	memset(head,-1,sizeof head);
	memset(ban,0,sizeof ban);
}
void add(int u,int v,ll w){
	e[cnt].v=v;
	e[cnt].w=w;
	e[cnt].nex=head[u];
	head[u]=cnt++;
}
//是否为有向图
void add2(int u,int v,ll w,bool op){
	add(u,v,w);
	add(v,u,op?0:w);
}
bool bfs(int s,int t){
	queue<int>q;
	memset(level,0,sizeof level);
	level[s]=1;
	q.push(s);
	while(!q.empty()){
		int x=q.front();
		q.pop();
		if(x==t)return 1;
		for(int u=head[x];~u;u=e[u].nex){
			int v=e[u].v;ll w=e[u].w;
			if(!level[v]&&w){
				level[v]=level[x]+1;
				q.push(v);
			}
		}
	}
	return 0;
}
ll dfs(int u,ll maxf,int t){
	if(u==t)return maxf;
	ll ret=0;
	for(int i=head[u];~i;i=e[i].nex){
		int v=e[i].v;ll w=e[i].w;
		if(level[u]+1==level[v]&&w){
			ll MIN=min(maxf-ret,w);
			w=dfs(v,MIN,t);
			e[i].w-=w;
			e[i^1].w+=w;
			ret+=w;
			if(ret==maxf)break;
		}
	}
	if(!ret)level[u]=-1;//优化,防止重搜,说明u这一路不可能有流量了 
	return ret;
}
ll Dinic(int s,int t){
	ll ans=0;
	while(bfs(s,t))
	ans+=dfs(s,INF,t);
	return ans;
}
int in(){
	int v;
	scanf("%d",&v);
	return v;
}
void link(int i){
	if(ban[i])return;
	if(sum[i]==sum[st]){
		add2(ss,i,1,1);
		for(int j=0;j<m;++j){
			int x=(i/ten[j])%10,y=i-x*ten[j];
			for(int k:{-1,1}){
				int nx=(x+k+10)%10,ny=y+nx*ten[j];
				if(ban[ny])continue;
				add2(i,ny,1,1);
			}
		}
	}
	else{
		add2(i,ee,1,1);
	}
}
int main(){
	ten[0]=1;
	for(int i=1;i<=6;++i)ten[i]=ten[i-1]*10;
	for(int i=1;i<=ten[5];++i)sum[i]=(sum[i/10]+(i%10))%2;
    scanf("%d",&ca);
    while(ca--){
    	init();
    	scanf("%d%d",&m,&n);
    	ss=ten[m];ee=ten[m]+1;
    	st=in();
    	for(int i=1;i<=n;++i){
    		ban[in()]=1;
    	}
    	for(int i=0;i<ten[m];++i){
    		if(i==st)continue;
    		link(i);
    	}
    	Dinic(ss,ee);
    	link(st);
    	puts(Dinic(ss,ee)?"Alice":"Bob");
    }
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/737527.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Endnotes引用

准备不用zetro了&#xff0c;主要学校endnotes免费 该说不说&#xff0c;zetro拖入pdf直接识别并导入的功能是真的好用&#xff0c;添加备注也方便 可惜文献太多放不下了&#xff0c;扩容要加钱。 啧。算了算了。 这里主要介绍Endnotes中的文献怎么在word内引用&#xff0c…

SpringBoot 插件化开发模式,强烈推荐!

一、前言 插件化开发模式正在很多编程语言或技术框架中得以广泛的应用实践&#xff0c;比如大家熟悉的jenkins&#xff0c;docker可视化管理平台rancher&#xff0c;以及日常编码使用的编辑器idea&#xff0c;vscode等&#xff0c;随处可见的带有热插拔功能的插件&#xff0c;…

BitLocker 驱动器加密管理

为了有效地保护数字数据&#xff0c;应对其进行加密&#xff0c;以便只有授权用户才能访问。BitLocker 是某些 Windows 操作系统上可用的本机加密工具&#xff0c;可以为个人用户轻松加密Windows计算机。 什么是 BitLocker 加密 BitLocker 加密是 Windows 操作系统的内置安全…

STM32实现气压传感器测量(BMP180)

目录 0.接线设计 1.功能描述 2.四种方式实现大气压采集 3.模块选择 4.编程环境 5.模块主要参数 6.代码实现 1&#xff09;标准库模拟IIC实现气压值采集 2&#xff09;标准库硬件IIC实现气压值采集 3&#xff09;HAL库模拟IIC实现气压值采集 4&#xff09;HAL库硬件IIC实…

分享一次腾讯云轻量应用服务器被攻击

腾讯云轻量应用服务器&#xff0c;centOS。在上面装了redis、rabbit mq等服务&#xff0c;开着端口&#xff0c;结果被入侵了。 发现问题是通过腾讯云发来的邮件&#xff0c; 首先进到主机安全控制台&#xff0c;左侧这里进主机列表 然后可以看到自己的主机情况&#xff0c;防…

ROS:机器人系统仿真

目录 一、概念二、作用2.1仿真优势:2.2仿真缺陷: 三、组件3.1URDF3.2rviz3.3gazebo 一、概念 通过计算机对实体机器人系统进行模拟的技术&#xff0c;在 ROS 中&#xff0c;仿真实现涉及的内容主要有三:对机器人建模(URDF)、创建仿真环境(Gazebo)以及感知环境(Rviz)等系统性实…

HTML特性(attribute)和DOM属性(property)

文章目录 定义位置不同attributeproperty 范围不同属性映射行为区别数据类型不同大小写敏感区别相同属性返回值可能不同DOM 属性具有写保护 定义位置不同 attribute 是 HTML 标签上的某个属性&#xff0c;如 id、class、value 等以及自定义属性,定义后会呈现在标签上 proper…

赛效:如何在线编辑图片

1&#xff1a;点击导航栏里的“图片编辑”。 2&#xff1a;点击打开图片或者拖放打开图片。 3&#xff1a;左侧几十种工具&#xff0c;你可以用来在线编辑图片。 4&#xff1a;编辑完成后点击页面右上角的“下载”按钮&#xff0c;根据提示登录账号下载图片就可以了。 如果你想…

2023广州建博会:鸿雁总裁王米成详解全屋智能的发展脉络

全屋智能落地的模式有很多&#xff0c;但鸿雁依托其智能面板优势&#xff0c;逐渐探索出一条属于鸿雁的全屋智能发展路径和商业模式。 智哪儿创始人、总编彭安军&#xff08;左&#xff09;&#xff0c;鸿雁电器总裁王米成&#xff08;右&#xff09; 在2023年的广州建博会上&a…

【Linux从入门到放弃】进程状态的理解以及什么是僵尸进程和孤儿进程?

&#x1f9d1;‍&#x1f4bb;作者&#xff1a; 情话0.0 &#x1f4dd;专栏&#xff1a;《Linux从入门到放弃》 &#x1f466;个人简介&#xff1a;一名双非编程菜鸟&#xff0c;在这里分享自己的编程学习笔记&#xff0c;欢迎大家的指正与点赞&#xff0c;谢谢&#xff01; 文…

你知道什么是基于StyleNeRF的conditional GAN模型吗

随着深度学习技术的不断发展&#xff0c;生成对抗网络&#xff08;GAN&#xff09;已经成为了人工智能研究和应用中的重要组成部分。其中&#xff0c;GAN可以被用来生成高质量的图像、视频等内容&#xff0c;这为娱乐产业和数字化制作带来了新的机遇和挑战。本文将介绍一种基于…

numpy 笔记 pad

1 基本介绍 对原本的矩阵进行填充 numpy.pad(array, pad_width, modeconstant, **kwargs) array待填充的矩阵pad_width要填充的位置mode填充方式 2 参数举例 2.0 使用的数据 import numpy as np anp.arange(12).reshape(3,4) aarray([[ 0, 1, 2, 3],[ 4, 5, 6, 7],…

【分布式 】 ELK 企业级日志分析系统

目录 一、ELK概述1.1 ELK简介1.2 为什么要使用ELK1.3 完整日志系统基本特征1.4 ELK的工作原理 二、搭建ELK2.1 ELK Elasticsearch 集群部署&#xff08;在Node1、Node2节点上操作&#xff09;node1 操作node2 同node1操作 2.2 安装 Elasticsearch-head 插件ELK Logstash 部署&a…

作为一个测试工程师,你选择python还是java?

问&#xff1a;“你平时工作中&#xff0c;用java多还是用python多”&#xff1f; 答&#xff1a;“都还可以&#xff0c;根据具体的场景选择不同的语言”。 问&#xff1a;“比如说呢”&#xff1f; 答&#xff1a;“开发自己的测试平台&#xff0c;肯定会选择java&#xf…

Stable Diffusion - ControlNet 插件中扩展局部重绘 InpaintOnly + LaMa 的算法与应用

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/131643131 LaMa: https://github.com/advimman/lama Paper: Resolution-robust Large Mask Inpainting with Fourier Convolutions LaMa: Large…

ActiveMQ详细入门教程系列

一、什么是消息中间件 两个系统或两个客户端之间进行消息传送&#xff0c;利用高效可靠的消息传递机制进行平台无关的数据交流&#xff0c;并基于数据通信来进行分布式系统的集成。通过提供消息传递和消息排队模型&#xff0c;它可以在分布式环境下扩展进程间的通信。 消息中…

ABeam中国2023社招 | ABeam旗下德硕管理咨询(深圳)招贤纳士

岗位需求 SAP Basis顾问 岗位职责 ■ 参与公司的SAP售前项目&#xff0c;负责Basis相关工作的方案制定 ■ 参与公司既有SAP运维项目&#xff0c;负责Basis相关的课题对应&#xff0c;系统改善等 ■ 负责SAP系统的Basis实施&#xff0c;SAP产品系统安装、升级、迁移、数据归档…

spring-java面向切面拦截器

切面&#xff0c;就是可以在代码执行的时候&#xff0c;在它执行的前面添加一个东西&#xff0c;一般我们用来做登陆拦截器验证以及敏感词的过滤。 他就3个东西&#xff0c;指定切点&#xff08;要执行的代码&#xff09;&#xff0c;before代码执行前面加东西。after代码后加东…

AC220V转负压5V芯片方案-220v转-5vic

AC220V到负压5V的电路转换 问题描述 --------- 如何将AC220V电压转换为负压5V输出&#xff0c;并且在输入电压范围为45V至265V的情况下工作&#xff1f;还要求该电路能够提供可调的电流范围&#xff0c;从100mA至2A。同时&#xff0c;所需的芯片为AH8699&#xff08;在700mA以…

BaGet做了一个Nuget私有服务器,Nginx代理之后还是会请求被代理得地址

Nuget搭建和使用可以参考官网得文档 https://loic-sharma.github.io/BaGet/installation/docker/ 这是我用Nginx代理之后出现得问题&#xff0c;观察请求url和响应回来得配置。配置中得ip地址得url是我被代理得下游地址&#xff0c;所以是无法访问的。 我原本以为是要去server…