• Jzoj2308 聚会


      Tzdin想组织一个圣诞晚会。N位女士和M位男士(M>=N)会被邀请参加这个聚会。在聚会的开始,Tzdin会派发一些写着某位男士信息的卡片给每位女士;每位女士都会收到若干张这种卡片。然后每位女士可以从她收到的卡片里挑选一位男士作为她的伴侣。我们可以认为经过Tzdin的引导,每位女士都一定可以挑选到一位男士作为他的伴侣,而每位男士最多成为1位女士的伴侣。Tzdin想知道的是,有哪些男士,无论女士们怎么选择,最终都一定会拥有伴侣。

    著名的稳定婚姻问题

    好了不瞎扯,我们来看看怎么用二分图来解决这个问题

    我们先做一次最大匹配,让后看看对于每一个被匹配的男士,如果匹配他的女士不能被匹配到除该男士以外的人,那么答案+1,因为匹配总是是确定的,为n,这个条件很重要

    匈牙利真是一个优美的算法,真的可以和Dijkstra媲美了

    #pragma GCC optimize("O3")
    #pragma G++ optimize("O3")
    #include<vector>
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define N 1010
    #define clear(t) memset(t,0,sizeof t)
    using namespace std;
    vector<int> G[N];
    int n,m,f[N],g[N],vis[N];
    bool match(int x){
    	for(int v,i=0;i<G[x].size();++i)
    		if(!vis[v=G[x][i]]){
    			vis[v]=1;
    			if(!f[v] || match(f[v])){ f[v]=x; return 1; }
    		}
    	return 0;
    }
    int main(){
    	scanf("%d%d",&n,&m);
    	for(int x,y,i=1;i<=n;++i)
    		for(scanf("%d",&x);x--;G[i].push_back(y)) scanf("%d",&y);
    	for(int i=1;i<=n;++i) clear(vis),match(i); memcpy(g,f,sizeof f);
    	for(int i=1;i<=m;++i)
    		if(g[i]){
    			clear(vis); vis[i]=1; 
    			memcpy(f,g,sizeof g);
    			if(!match(f[i])) printf("%d
    ",i);
    		}
    }


  • 相关阅读:
    Oracle面试题目及解答
    java -jar Incompatible argument to function
    plsql 查询到别的用户下面的表
    redis数据类型[string 、list 、 set 、sorted set 、hash]
    redis-cli 常用命令
    js判断浏览器,包括Edge浏览器
    HTMl5的sessionStorage和localStorage
    JS实现密码加密
    sprintf.js
    js-crc32
  • 原文地址:https://www.cnblogs.com/Extended-Ash/p/8449244.html
Copyright © 2020-2023  润新知