【题解】P4055 [JSOI2009] 游戏

link

题目大意

题目说得比较清楚。

题解

前置知识:二分图最大匹配、基础博弈论。

每个点只能走一次的四联通点阵,可以想到二分图匹配。

将其套路地奇偶分点,相邻两点连边(显然不能为 #)。

先求一个最大匹配。

如果是完美匹配,那么 LOSE. 因为小 AA 将棋子放到任意一点,小 YY 都能走匹配边走到另一部,小 AA 就只能走非匹配边。每一点都有一条匹配边,最后小 YY 会走最后一条匹配边,这时所有点都走完了。小 AA 败。

现在考虑 WIN. 首先,若小 AA 选择非匹配点,那么小 AA 必胜。显然,非匹配点的邻接点都为匹配点,否则就不是最大匹配。当小 AA 放下棋子后,小 YY 走到匹配点上。然后,小 AA 走匹配边。则小 YY 此时只能走非匹配边。以非匹配点为开始的一条路径,路径的结尾只能是匹配点。这个点只有一条边连出,为匹配边。最后,小 AA 会通过这条匹配边走到结尾,小 AA 胜。

所以小 AA 选非匹配点时胜利。

再来观察下图。黑点为匹配点,边权为 1 1 1 的是匹配边。

这是一张图片

我们还有另一种方案:

在这里插入图片描述那么点 1 1 1 5 5 5 都是必胜点。

由此断言:答案为非最大匹配必须点

如果一个点 p p p非最大匹配必须点,那么存在一个最大匹配,使点 p p p 不是匹配点。在这个最大匹配上实行上述方案,小 AA 必胜。

我们发现,只需要对一个点尝试增广,如果增广出一条路径,长度与当前最大匹配的路径长度相等,那这个点就是一个非最大匹配必须点。

由于一个点可能在 X X X 部,也可能在 Y Y Y 部,分类讨论的话要写两个增广函数。可以将两部记录匹配点的数组 c x cx cx c y cy cy 合并,统一为 c x y cxy cxy c x y i cxy_i cxyi 记录点 i i i 对应的匹配点编号。这样的话需要建双向边,所以其实是用增大常数的代价换来较小的编程复杂度。

时间复杂度 O ( n 4 ) O(n^4) O(n4).

代码

#include <bits/stdc++.h>
using namespace std;
const int N = 40005;//不能开太大,否则 memset 时会 TLE
int n, m, cnt = 0, fir[N], nxt[N], to[N], vis[N], cxy[N], p[105][105], tot = 0, xt, cans = 0;
char a[105][105];
int dx[5] = {0, 1, 0, -1};
int dy[5] = {1, 0, -1, 0};
struct node {
    int x, y;
} ans[N];
void ade(int u, int v) {
    cnt++, nxt[cnt] = fir[u], fir[u] = cnt, to[cnt] = v;
    cnt++, nxt[cnt] = fir[v], fir[v] = cnt, to[cnt] = u;
}
void getp() {//重标号
    for (int i = 1; i <= n; i++)
        for (int j = ((i & 1) ? 1 : 2); j <= m; j += 2)
            if (a[i][j] == '.')
                p[i][j] = ++tot;
    xt = tot;
    for (int i = 1; i <= n; i++)
        for (int j = ((i & 1) ? 2 : 1); j <= m; j += 2)
            if (a[i][j] == '.')
                p[i][j] = ++tot;
}
void ADE(int x, int y) {//将 (x,y) 与邻接点连边
    for (int i = 0; i < 4; i++) {
        int xx = x + dx[i], yy = y + dy[i];
        if (xx >= 1 && xx <= n && yy >= 1 && yy <= m && a[xx][yy] == '.') ade(p[x][y], p[xx][yy]);
    }
}
int dfs(int r) {//找增广路径
    vis[r] = 1;
    for (int i = fir[r]; i; i = nxt[i])
        if (!vis[to[i]]) {
            vis[to[i]] = 1;
            if (!cxy[to[i]] || dfs(cxy[to[i]])) {
                cxy[cxy[r]] = 0, cxy[r] = to[i], cxy[to[i]] = r;
                return 1;
            }
        }
    return 0;
}
void match() {
    for (int i = 1; i <= xt; i++)
        if (!cxy[i])
            memset(vis, 0, sizeof(vis)), dfs(i);
}
int main() {
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++) scanf("%s", a[i] + 1);
    getp();
    for (int i = 1; i <= n; i++)
        for (int j = ((i & 1) ? 1 : 2); j <= m; j += 2)//只枚举偶点
            if (a[i][j] == '.')
                ADE(i, j);
    match();//先求一种最大匹配方案
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            if (a[i][j] == '.') {
                memset(vis, 0, sizeof(vis));
                if (!cxy[p[i][j]] || dfs(cxy[p[i][j]])) ans[++cans].x = i, ans[cans].y = j;
            }
    if (!cans) { printf("LOSE"); return 0; }//没有非匹配点
    printf("WIN\n");
    for (int i = 1; i <= cans; i++) printf("%d %d\n", ans[i].x, ans[i].y);
    return 0;
}

END

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

5G/V2X赛道「重启」

在提升高阶智能驾驶安全性和感知冗余能力的道路上&#xff0c;除了激光雷达、高精度地图及定位&#xff0c;还有一项技术可能即将掀起一场新的风暴。 就在今年3月&#xff0c;作为全球通信领域的年度风向标 — 2023世界移动通信大会&#xff08;MWC&#xff09;上&#xff0c;…

基于html+css的盒子展示6

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

第七回:如何使用GirdView Widget

文章目录概念介绍使用方法示例代码经验总结我们在上一章回中介绍了Image Widget,本章回中将介绍 GirdView这种Widget&#xff0c;闲话休提&#xff0c;让我们一起Talk Flutter吧。概念介绍 在Flutter中使用GirdView表示网格状的布局&#xff0c;类似日常办公中使用的Excel,它和…

win10彻底永久关闭自动更新【亲测有效】

一、禁用Windows Update服务 1、同时按下键盘 Win R&#xff0c;打开运行对话框&#xff0c;然后输入命令 services.msc &#xff0c;点击下方的“确定”打开服务&#xff0c;如下图所示。 2、找到 Windows Update 这一项&#xff0c;并双击打开&#xff0c;如图所示。 3、右击…

MySQL-中间件mycat(二)

目录 &#x1f341;部署主从复制 &#x1f341;mycat读写分离 &#x1f342;修改配置文件 &#x1f342;设置balance与writeType &#x1f342;设置switchType与slaveThreshold &#x1f342;启动程序 &#x1f342;验证读写分离 &#x1f341;垂直拆分-分库 &#x1f342;实现…

openvpn (用户名密码模式)

目录 一、介绍 1、定义 2、原理 3、加密和身份验证 二、在centos 7.5上搭建openvpn 1、安装openvpn 和easy-rsa&#xff08;该包用来制作ca证书&#xff09; 2、配置/etc/openvpn/ 目录 3、创建服务端证书及key 4、创建客户端证书 5、把服务器端必要文件放到etc/openvpn/ 目录下…

融云出海赋能会干货回顾 | 用户增长、场景玩法、安全合规实用指南

近期&#xff0c;“纵浪潜海 2023 融云社交泛娱乐出海赋能会”在上海、广州相继举行。移步【融云全球互联网通信云】&#xff0c;回复【出海】获取PPT。 作为更专业的出海服务商&#xff0c;融云联合多家出海服务企业&#xff0c;从热门出海地区的特性洞察、玩法解决方案、技…

ElasticSearch索引文档写入和近实时搜索

一、基本概念 1.Segments In Lucene 众所周知&#xff0c;ElasticSearch存储的基本单元Shard&#xff0c;ES中一个Index可能分为多个Shard&#xff0c;事实上每个Shard都是一个Lucence的Index&#xff0c;并且每个Lucene Index由多个Segment组成&#xff0c;每个Segment事实上…

关键词词库制作-搜索词分析工具

关键词词库制作 关键词词库是一种帮助SEO和SEM优化的工具&#xff0c;它可以帮助您确定关键词的流行程度、竞争程度、搜索意图和其他相关信息等等。以下是一些关键词词库制作的方法&#xff1a; 收集关键词&#xff1a;首先需要收集相关的关键词&#xff0c;这可能涉及到您的业…

Transformer中的注意力机制及代码

文章目录1、简介2、原理2.1 什么是注意力机制2.2 注意力机制在NLP中解决了什么问题2.3 注意力机制公式解读2.4 注意力机制计算过程3、单头注意力机制与多头注意力机制4、代码4.1 代码14.2 代码21、简介 最近在学习transformer&#xff0c;首先学习了多头注意力机制&#xff0c…

[ vulnhub靶机通关篇 ] 渗透测试综合靶场 DC-5 通关详解 (附靶机搭建教程)

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…

[Data structure]队列环形队列 | 一文带你彻底搞懂队列和环形队列(内附详细图解和代码实现)

⭐作者介绍&#xff1a;大二本科网络工程专业在读&#xff0c;持续学习Java&#xff0c;努力输出优质文章 ⭐作者主页&#xff1a;逐梦苍穹 ⭐所属专栏&#xff1a;数据结构。数据结构专栏主要是在讲解原理的基础上拿Java实现 ⭐如果觉得文章写的不错&#xff0c;欢迎点个关注一…

淘宝/天猫店铺订单数据导出、销售报表、数据分析

最近有厂商提出想把天猫店铺的数据拿到后台ERP管理系统中&#xff0c;并能实现线下打印电子面单功能。接手这个需求按照度娘给的指引&#xff0c;申请天猫开发者帐号&#xff0c;但是。。。大厂把订单传送接口关了&#xff0c;只对厂商自研软件开放&#xff0c;还需要租用聚石塔…

「MongoDB」时序数据库和MongoDB第二部分-模式设计最佳实践

在上一篇博客文章时间序列数据与MongoDB&#xff1a;第一部分-简介中&#xff0c;我们介绍了时间序列数据的概念&#xff0c;然后介绍了一些可以用于帮助收集时间序列应用程序需求的发现问题。对这些问题的回答有助于指导支持大容量生产应用程序部署所需的模式和MongoDB数据库配…

[牛客101] 二叉树的层序遍历

这道题会考察很多知识点,这里专门进行详解 文章目录题目描述二. 题目分析完整代码题目描述 二. 题目分析 首先,我们会想到存储方式为二维数组.数组每一行存储一层的结点.怎么确定每一行要存储几个结点呢.由于节点与节点之间存在父子关系,所以,在存储某一层的结点时,就可以通过…

Python图像处理【12】基于小波变换执行图像去噪

基于小波变换执行图像去噪0. 前言1. 小波变换基础2. 小波变换去噪原理3. 使用 pywt 执行小波变换图像去噪4. 使用 scikit-image 执行小波变换图像去噪4.1 循环旋转技术4.2 改进图像去噪质量小结系列链接0. 前言 小波 (wavelets) 变换是表示和分析多分辨率图像的通用方法&#…

栈的实现及相关OJ题

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了 博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点!人生格言&#xff1a;当你的才华撑不起你的野心的时候,你就应该静下心来学习! 欢迎志同道合的朋友一起加油喔&#x1f9be;&am…

再摘一枚重要奖项!腾讯安全获得云安全联盟CSA 2022安全金盾奖

4月13日&#xff0c;第六届云安全联盟大中华区大会&#xff08;CSA GCR Congress&#xff09;在上海举办&#xff0c;大会由联合国数字安全联盟、上海市经济和信息化委员会、上海市委网络安全和信息化委员会办公室、上海市普陀区人民政府指导&#xff0c;云安全联盟大中华区主办…

vue面试题2023

1.$route和$router的区别? routes : 数组。 路由匹配规则 router &#xff1a; 对象。 路由对象 $router &#xff1a; 对象。 用于跳转路由 和 传递参数 $route &#xff1a;对象。 用于接收路由跳转参数 1.Vue的生命周期方法有哪些&#xff1f; - beforeCreate 初始化实…

【产品应用】一体化步进伺服电机在高速异形插件机的应用

随着科技的不断发展&#xff0c;自动化生产设备在各个行业中得到了广泛的应用。高速异形插件机作为自动化生产设备中的一种&#xff0c;其核心部件之一就是一体化步进伺服电机。本文将详细介绍一体化步进伺服电机在高速异形插件机中的应用。 01.设备简介 高速异形插件机是一种…