• CF1147F Zigzag Game & 稳定婚姻问题学习笔记


    CF1147F Zigzag Game

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

    我网络流做不动了,DS做不动了,DP做不动了,特别自闭。于是博弈论之神(就是随手切3500博弈的那种) (color{black}{ exttt{F}}color{red}{ exttt{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
    "),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
    ",mch[x]),fflush(stdout);
    		scanf("%d",&x);if(!~x)break;
    	}
    }
    signed main(){for(int T=read();T;--T)Main();}
    
  • 相关阅读:
    棋盘问题 POJ
    Fire! UVA
    走迷宫(bfs, 最短路)
    ASP-Command-SQL格式
    ASP连接数据库SQLServer
    Bootstrap学习-导航条-分页导航
    Bootstrap导航栏头部错位问题
    SQLServer判断一个IP是否在一个IP段里
    MySQL合并多行
    CSS图片居中,多余隐藏
  • 原文地址:https://www.cnblogs.com/zzctommy/p/14044374.html
Copyright © 2020-2023  润新知