CF1147F Zigzag Game

这题太神仙了,不得不记录一下。

我网络流做不动了,DS做不动了,DP做不动了,特别自闭。于是博弈论之神(就是随手切3500博弈的那种) \(\color{black}{\texttt{F}}\color{red}{\texttt{orever_Pursuit}}\) 建议我去学博弈论。

当时看到这题只有两个标签:博弈,交互。就去做了。看到是和交互库玩游戏,感觉很好玩。发现不会,就问了FP。他也不会。然后看题解,发现根本不是博弈(恼。但是这个知识比较重要,还是记一下。准确来说,这是60多年前的论文题/fad,没做过很难现场搞出来。


题解

可以证明选Bob一定必胜(即选择先放棋子)。

首先,我们可以默认我们拿到的操作符是 I ,并且我们选的是左边的数。如果恰好一个有变化,直接把所有边权取相反数即可。

如果必胜,那么意味着我们选了边 \(<a,b>\) ,对方选了 \(<b,c>\) ,我们一定可以找到 \(<c,d>\) ,满足 \(w_{a,b}>w_{b,c},w_{c,d}>w_{b,c}\) 。

这就是稳定婚姻问题,找到一组可行的匹配即可,直接写就完事了简直生草,国外还有论文题。

更明显一点:如果 \(b\) 认为 \(c\) 比 \(a\) 优,那么 \(c\) 一定不能认为 \(b\) 比 \(d\) 优,否则不稳定。

注意两边点的“更优”定义是不同的。左边的点认为更大的更优,右边的点认为更小的更优。

这题没了。可是蒟蒻不会稳定婚姻问题,于是学习笔记就顺带写了(


稳定婚姻问题学习笔记

男孩女孩太不习惯了 ,我们就用这道题的题面,左边的点匹配右边的点

问题定义

给一张完全二分图(你硬说男生在左女生在右也行),每一对左边的点与右边的点之间都有一个评分 \(w_{i,j}\),要求把点两两匹配,满足:

设点 \(a,c\) 在同一边,点 \(b,d\) 在另一边,当前 \((a,b),(c,d)\) 匹配。那么对于所有这种 \((a,b,c,d)\) 不能存在 \(w_{b,a}<w_{b,c}\) (\(b\) 认为\(c\) 比 \(a\) 优)且 \(w_{c,b}>w_{c,d}\) (\(c\) 认为\(b\) 比 \(d\) 优)的情况。

如果存在,那么显然 \(b,c\) 会组成一对,因为这对于 \(b,c\) 来说都更优,那么他们会各自拒绝自己原来的匹配,就不稳定了。

算法流程

定义数组 \(mch_i\) 表示 \(i\) 的匹配。

  • 每次取出一个左边的没有匹配的点。

    • 如果他当前最优的匹配 \(v\) 没有匹配,那么 \(u\) 匹配 \(v\) 。
    • 如果 \(v\) 有匹配并且认为 \(u\) 比他当前的匹配更优,那么 \(u,v\) 匹配,原来的 \(mch_v\) 匹配取消,即 \(mch_v\) 被 \(v\) 拒绝了。
  • 如果每一个节点都有匹配,那么婚姻稳定,退出。

注意 最优匹配 指的是还没有拒绝 \(u\) 的点中,\(u\) 认为最优的匹配。

正确性证明

可行性

假设算法结束后,有一个左边的点和右边的点没有匹配上(存在没匹配那么左右至少各一个点点匹配)

  • 如果一个右边的点被尝试匹配过了,必然有匹配。
  • 如果左边的点一直没有匹配,那么会尝试匹配右边所有的点。

所以右边必然匹配满,那么就不存在失配的问题。

时间复杂度

可以发现,每一个左边的点至多尝试 \(n\) 次与右边的点匹配,那么上界 \(O(n^2)\)

性质

可以发现主动方可以选择到他可以匹配到的最优的匹配。


\(\mathcal{Code}\) (稳定婚姻部分有详细注释。主函数如果你认真看了上面的讲解应该能写出来)

#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define mkp(x,y) make_pair(x,y)
#define pb(x) push_back(x)
#define sz(v) (int)v.size()
typedef long long LL;
typedef double db;
template<class T>bool ckmax(T&x,T y){return x<y?x=y,1:0;}
template<class T>bool ckmin(T&x,T y){return x>y?x=y,1:0;}
#define rep(i,x,y) for(int i=x,i##end=y;i<=i##end;++i)
#define per(i,x,y) for(int i=x,i##end=y;i>=i##end;--i)
inline int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=0;ch=getchar();}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return f?x:-x;
}
const int N=55;
int n,w[N][N],mch[N<<1],kth[N<<1],rk[N<<1][N<<1],ID;
vector<int>e[N<<1];
bool cmp1(const int&a,const int&b){return w[ID][a-n]>w[ID][b-n];}
bool cmp2(const int&a,const int&b){return w[a][ID-n]<w[b][ID-n];}
void init(){//稳定婚姻问题模板
fill(mch+1,mch+n*2+1,0),fill(kth+1,kth+n*2+1,0);
queue<int>q;
rep(i,1,n){
e[i].resize(n+1),e[i+n].resize(n+1);//每一个点的匹配边大小是 n
rep(j,1,n)e[i][j]=j+n,e[i+n][j]=j;//拉边
ID=i,sort(e[i].begin()+1,e[i].begin()+n+1,cmp1);
ID=i+n,sort(e[i+n].begin()+1,e[i+n].begin()+n+1,cmp2);//两边的点对于“优”的定义不同
rep(j,1,n)rk[i][e[i][j]]=j,rk[i+n][e[i+n][j]]=j;//处理对于 i 这个节点的所有可能的匹配 j 在 i 看来的优秀程度
q.push(i);//没有匹配的点丢进队列
}
while(!q.empty()){
int u=q.front();q.pop();//找到一个没有匹配的点
int v=e[u][++kth[u]];//kth 是 u 当前最优的匹配排名
if(!mch[v])mch[u]=v,mch[v]=u;//v 还没有匹配
else if(rk[v][u]<rk[v][mch[v]]){
if(mch[v]<=n)q.push(mch[v]);//mch[v] 失去匹配了,重新丢进队列找匹配
mch[mch[v]]=0,mch[v]=u,mch[u]=v;//v 认为 u 更优
}else q.push(u);//没匹配上,丢进去接着找
}
}
void Main(){
scanf("%d",&n);
rep(i,1,n)rep(j,1,n)w[i][j]=read();
printf("B\n"),fflush(stdout);
char fyyAK[5];int x;
scanf("%s%d",fyyAK,&x);
if((fyyAK[0]=='I')^(x>n))rep(i,1,n)rep(j,1,n)w[i][j]*=-1;
init();
while("fyy txdy"){//只能膜拜!
printf("%d\n",mch[x]),fflush(stdout);
scanf("%d",&x);if(!~x)break;
}
}
signed main(){for(int T=read();T;--T)Main();}

CF1147F Zigzag Game & 稳定婚姻问题学习笔记的更多相关文章

  1. 算法笔记_138:稳定婚姻问题(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 何为稳定婚姻问题? 有一个男士的集合Y = {m1,m2,m3...,mn}和一个女士的计划X = {n1,n2,n3,...,nn}.每一个男士有 ...

  2. 我的Android进阶之旅------>Android中编解码学习笔记

    编解码学习笔记(一):基本概念 媒体业务是网络的主要业务之间.尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析.应用开发.释放license收费等等 ...

  3. Hadoop入门学习笔记---part2

    在<Hadoop入门学习笔记---part1>中感觉自己虽然总结的比较详细,但是始终感觉有点凌乱.不够系统化,不够简洁.经过自己的推敲和总结,现在在此处概括性的总结一下,认为在准备搭建ha ...

  4. 《Linux内核设计与实现》课本第五章学习笔记——20135203齐岳

    <Linux内核设计与实现>课本第五章学习笔记 By20135203齐岳 与内核通信 用户空间进程和硬件设备之间通过系统调用来交互,其主要作用有三个. 为用户空间提供了硬件的抽象接口. 保 ...

  5. Android自动化学习笔记:编写MonkeyRunner脚本的几种方式

    ---------------------------------------------------------------------------------------------------- ...

  6. AngularJS 1.2.x 学习笔记(表单校验篇)

    https://my.oschina.net/cokolin/blog/526911 摘要: 本文首发于 blog.csdn.net/vipshop_ebs/article/details/39472 ...

  7. Nodejs学习笔记(二)——Eclipse中运行调试Nodejs

    前篇<Nodejs学习笔记(一)——初识Nodejs>主要介绍了在搭建node环境过程中遇到的小问题以及搭建Eclipse开发Node环境的前提步骤.本篇主要介绍如何在Eclipse中运行 ...

  8. android cocos2d-x for Android安装和学习笔记(请用adt-bundle21.1或以上导入)

    引用:http://weimingtom.iteye.com/blog/1483566 (20121108)注意:这篇文章用cdt编译ndk工程的内容已过时(现在可以用adt-bundle,避免配置繁 ...

  9. 《Linux内核设计与实现》课本第一章&第二章学习笔记

    <Linux内核设计与实现>课本学习笔记 By20135203齐岳 一.Linux内核简介 Unix内核的特点 Unix很简洁,所提供的系统调用都有很明确的设计目的. Unix中一切皆文件 ...

随机推荐

  1. Fiddler的一系列学习瞎记2(没有章法的笔记)

    前言 不适合小白,因为很多需要小白来掌握的东西我都没有写,就是补充自己还不会的东西,所以,有些同僚看起来可能感觉不是很清楚. 正文: 瞎记2-什么是代理服务器 1.web代理服务器,是在客户端和服务器 ...

  2. 如何通过iptables代理访问内网

    场景 A机器能够联通内网机器,B机器能够联通A机器,但是访问不到内网机器,场景是希望通过A机器能够转发直接联通局域网内的其它机器 机器IP 内网为172.0.0.x/24 A机器为172.0.0.10 ...

  3. Win10系统下安装VC6.0教程

    学习一门语言最重要的一步是搭建环境,许多人搭建在搭建环境上撞墙了,就有些放弃的心理了:俗话说,工欲善其事,必先利其器:所以接下来我们进行学习C的第一步下载编程所用的工具;当然也有其它的软件,只不过初学 ...

  4. Java 添加、读取、删除Excel中的图表趋势线

    本文以Java示例介绍如何在Excel中添加趋势线,以及读取趋势线公式.通过文中的方法可支持添加6种不同类型的趋势线,包括Linear.Exponential.Logarithmic.Moving A ...

  5. cookie和session的关系和区别

    1.为什么会用到cookie和session 由于http请求是一种无状态的请求,一旦数据交换完毕便会关闭请求,再次交换数据则要再次发起请求,所以服务端无法通过连接追踪会话,确定用户身份,而cooki ...

  6. tp5 上传图片(自定义图片路径)

    控制器调用 /** * [goods_addimg 图片上传] * @return [type] [description] */ public function addimg(){ if (requ ...

  7. js替换div里的内容

    <!DOCTYPE html><html><head><meta charset="utf-8"><title>< ...

  8. ERP应收应付进阶操作与子流程--开源软件诞生29

    赤龙ERP应收应付进阶讲解--第29篇 用日志记录"开源软件"的诞生 [进入地址 点亮星星]----祈盼着一个鼓励 博主开源地址: 码云:https://gitee.com/red ...

  9. 推荐一款比迅雷下载速度快的mac下载器

    Folx和迅雷是2款支持在Mac系统上进行文件资源下载的工具,两者都支持BT种子资源的下载和直链下载,但Folx还另外支持了下载计划的自定义和智能限速功能.本文主要是为了比较Folx和迅雷在下载同一资 ...

  10. Java数据结构(七)—— 排序算法

    排序算法(Sort Algorithm) 排序算法介绍和分类 将一组数据,依指定顺序进行排列 排序的分类 内部排序 指将需要处理的所有数据都加载到内部存储器中进行排序 外部排序 数据量过大,无法全部加 ...