@description@

给定一个 2n 个结点的完全二分图,1~n 在左边,n+1~2n 在右边。第 i 个点与第 j+n 个点的边权为 aij,且 aij 互不相同。

Alice 与 Bob 在这个图上博弈。

一开始 Alice 选择 "increase" 或 "decrease",Bob 自动得到另一个。然后 Alice 选择点放置棋子,Bob 开始移动棋子,然后他们轮流移动棋子。但是不能移动到曾经到达过的点。

假如当前玩家选择 "increase",则该玩家接下来应该走一条比上一次边权大的边;反之如果选择 "decrease",应选一条比上一次小的边。

不能移动的人判负。

现在,你和评测机斗智斗勇。你可以选你是 Alice 还是 Bob,然后通过你自己的必胜策略战胜评测机。

(交互过程就不贴过来了,大家可以自己访问原题

@solution@

如果你有做过类似的题目(二分图上博弈,如 bzoj1443),你可能会更能够想到这道题的解法。

首先,你以为 Alice 既能决定 increase/decrease 又能决定起点很厉害?但是你手玩一下发现几乎都是 Bob 赢。

所以我们尝试构造出 Bob 的必胜策略。

对于这类二分图上博弈,必胜策略往往是顺着匹配边走。然而这道题边带权,我们不能求最大匹配。

我们尝试找到一类匹配,使得 Bob 沿着匹配边走是必胜的。以下假设 Alice 选择左侧点,并选择 increase,其他情况类似的。

Bob 沿着匹配边 (u, v) 前提是走这条匹配边 (u, v) 是合法的,即所有可能的博弈过程中经过 (u, v) 时前一条边都比这条边大。

假如说上一条匹配边为 (x, y),一种情况是 Alice 无法走 y -> u,即 w(x, y) > w(u, y)。

另一种情况选择走 y -> u。此时应该有 w(x, y) < w(u, y) 且 w(u, y) > w(u, v)。

即 w(x, y) > w(u, y) 或 w(u, y) > w(u, v) 时合法,反过来当 w(x, y) < w(u, y) < w(u, v) 时该匹配不合法。

带权的匹配?最大权匹配貌似不能应用于这道题。但是我们可以采用另一种带权匹配:稳定婚姻匹配(可以自行百度)。

我们把左边的点按 w 从小到大评估,右边的点按 w 从大到小评估,跑稳定婚姻匹配。

那么对于匹配的点对 (x, y) 与 (u, v),不会出现 w(u, v) > w(u, y) 且 w(x, y) < w(u, y) 的情况。即上述的不合法情况。

至于为什么 Bob 必胜,因为是完全图所以每个点都有匹配。

那么 Alice 无论走哪里,Bob 总可以找到对策。最后只可能 Alice 没有对策。

注意上面只讨论了一种情况:Alice 选择左侧点,并选择 increase。其他情况还需要进一步讨论。

@accepted code@

#include <cstdio>
#include <cstdlib>
using namespace std;
const int MAXN = 50;
bool cmp(int x, int y, bool t) {
if( !t ) return x > y;
else return x < y;
}
// x 优于 y ?
int a[MAXN + 5][MAXN + 5], n;
bool tg[MAXN + 5][MAXN + 5];
int lnk[2*MAXN + 5];
void get_match(bool t) {
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
tg[i][j] = false;
for(int i=1;i<=2*n;i++)
lnk[i] = 0;
while( true ) {
bool flag = true;
for(int i=1;i<=n;i++)
if( !lnk[i] ) {
int mx = 0;
for(int j=1;j<=n;j++)
if( !tg[i][j] && (mx == 0 || cmp(a[i][j], a[i][mx], t)) )
mx = j;
if( !lnk[mx+n] )
lnk[i] = mx + n, lnk[mx+n] = i;
else if( cmp(a[i][mx], a[lnk[mx+n]][mx], !t) ) {
int x = lnk[mx+n];
lnk[i] = mx + n, lnk[mx+n] = i;
tg[x][mx] = true, lnk[x] = 0;
}
else tg[i][mx] = true;
flag = false;
}
if( flag ) break;
}
}
/*
男左女右
0 : 男大女小
1 : 女大男小
*/
void solve() {
scanf("%d", &n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d", &a[i][j]);
puts("B"), fflush(stdout);
char str[5] = {}; int x;
scanf("%s%d", str, &x);
get_match( (str[0] == 'I') == (x <= n) );
while( true ) {
printf("%d\n", lnk[x]), fflush(stdout);
int op;
scanf("%d", &op);
if( op == -1 ) return ;
else if( op == -2 ) exit(0);
else x = op;
}
}
int main() {
int t; scanf("%d", &t);
while( t-- ) solve();
}

@details@

一开始没有看到不能经过已经访问过的点,想了半天。。。

关于稳定婚姻匹配的过程,这里附上一个简要版的,供以后复习用:

左边的男生不断去尝试右边还没有拒绝过他且他最喜欢的女生,女生从当前追求她的男生中选择最喜欢的作为暂时的伴侣。最终一定可以得到稳定婚姻匹配。

首先所有人都会有匹配,否则一个男生一定追求了所有女生,而所有女生一旦被追求就不会单身。矛盾。

男生不可能会与更喜欢的女生私奔,因为之前肯定已经追求过了,而女生的伴侣一定是越来越优,所以他就越来越没有机会。

理论上是 O(N^2) 的,每一对关系只会被 check 一次(被拒绝过就不会再追求)

但是好像没人卡这个时间。。。

同时,这个匹配是男生最优 (male-optimal) 且女生最差 (female-pessimal) 的匹配方案。

@codeforces - 1161F@ Zigzag Game的更多相关文章

  1. CodeForces 228D. Zigzag(线段树暴力)

    D. Zigzag time limit per test 3 seconds memory limit per test 256 megabytes input standard input out ...

  2. codeforces选做

    收录了最近本人完成的一部分codeforces习题,不定期更新 codeforces 1132E Knapsack 注意到如果只使用某一种物品,那么这八种物品可以达到的最小相同重量为\(840\) 故 ...

  3. Codeforces Round #557 (Div. 1) 简要题解

    Codeforces Round #557 (Div. 1) 简要题解 codeforces A. Hide and Seek 枚举起始位置\(a\),如果\(a\)未在序列中出现,则对答案有\(2\ ...

  4. Codeforces Round #557 题解【更完了】

    Codeforces Round #557 题解 掉分快乐 CF1161A Hide and Seek Alice和Bob在玩捉♂迷♂藏,有\(n\)个格子,Bob会检查\(k\)次,第\(i\)次检 ...

  5. [贪心,dp] Educational Codeforces Round 71 (Rated for Div. 2) C. Gas Pipeline (1207C)

    题目:http://codeforces.com/contest/1207/problem/C   C. Gas Pipeline time limit per test 2 seconds memo ...

  6. python爬虫学习(5) —— 扒一下codeforces题面

    上一次我们拿学校的URP做了个小小的demo.... 其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比 另外也可以写一个物理实验自动选课... 但是出于多种原因,,还是绕开这些敏感话题 ...

  7. [LeetCode] Zigzag Iterator 之字形迭代器

    Given two 1d vectors, implement an iterator to return their elements alternately. For example, given ...

  8. [LeetCode] Binary Tree Zigzag Level Order Traversal 二叉树的之字形层序遍历

    Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to ...

  9. [LeetCode] ZigZag Converesion 之字型转换字符串

    The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like ...

随机推荐

  1. canvas绘制video

    html <video style="position: relative; object-fit: fill;" preload="auto" id=& ...

  2. linux把普通用户添加到sudo组

    一.linux下把普通用户添加到sudo组的方式: 1. root权限下, 先cd到/etc目录下 2. 由于sudoers文件为只读权限,所以需要添加写入权限,chmod u+w sudoers 3 ...

  3. 手残,盘符前边多打一个空格导致的message d:\WEB_APP_QuChongFu\file\五月.xlsx (文件名、目录名或卷标语法不正确。)

    尝试读取并解析一个excel文件,一直提示错误 但是有个原始数据,导入就没问题 对比了一下,好像也就是字母d的大小写有区别 我先把大写的D改成小写的试试,如果是大小写问题,那应该抛出异常 好吧,好像并 ...

  4. 有趣的HTML5 Web SQL 数据库

    Web SQL 数据库 API 并不是 HTML5 规范的一部分,但是它是一个独立的规范,引入了一组使用 SQL 操作客户端数据库的 APIs. 核心方法 以下是规范中定义的三个核心方法: openD ...

  5. C# dataGridView_CellValueChanged事件

    C# 输入完以后立即更新缓冲区(DataGridView CheckBox列checked变化后就触发CellValueChanged事件) 在DataGridView添加如下的事件( Current ...

  6. 【Codeforces Round #430 (Div. 2) D】Vitya and Strange Lesson

    [链接]点击打开链接 [题意] 给出一个数组,每次操作将整个数组亦或一个数x,问得到的数组的结果中的mex.mex表示为自然数中第一个没有出现过的数. [题解] 异或的效果是可以累加的,所以不用每次都 ...

  7. Laravel 安装mysql、表增加模拟数据、生成控制器

    参考中文网教程: 安装mysql.表增加模拟数据 http://www.golaravel.com/post/2016-ban-laravel-xi-lie-ru-men-jiao-cheng-yi/ ...

  8. web前端学习(四)JavaScript学习笔记部分(1)-- JavaScript基础教程

    1.JavaScript基础教程 1.1.Javascript基础-介绍.实现.输出 1.1.1.JavaScript是互联网上最流行的脚本语言,这门语言可用于web和HTML,更可广泛用于服务端.p ...

  9. html DOM(CSS放置位置的问题)

    转载自: http://www.php.cn/div-tutorial-386900.html (本文对读者有帮助的话请移步支持原作者) 笔记: 这样会先加载css的样式,在渲染dom的时候已经知道了 ...

  10. Tiles Framework

    tiles framework 详解tiles framework 详解 就是一个页面模版引擎.可以渲染页面,属于视图层. 下面给你拷贝一份详细的tiles介绍,你可以初步了解一下. Tiles框架特 ...