codeforces1139E Maximize Mex 二分图匹配
Posted mountaink
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codeforces1139E Maximize Mex 二分图匹配相关的知识,希望对你有一定的参考价值。
题意:给出n个人,m个社团,每个人都有一个标号,一个能力值,并且属于一个社团,第i天的凌晨,第$k_i$个人会离开。每天每个社团最多派一个人出来参加活动。派出的人的能力值集合为S,求每天$MEXS$的最大值。
思路:这道题正着删人和倒着加人是一样的,并且很容易看出是二分图的题,加边显然要比删边容易操作,所以我们要倒着考虑。
只要想到了倒着考虑,剩下的就比较好想了。由于从小到大的能力值是必选的,我们把能力值作为左边的节点,社团作为右边的节点。每增加一个人就增加对应的边,每次匹配的时候上次的答案开始匹配,匹配到不能匹配位置,就是当前的答案了。由于二分图的特殊性,将当前这个点匹配了,肯定不会使之前的点变成失配点。
要注意的是,这里人的能力值最低是0,所以$match[x]=0$也是一个合法匹配,而大部分匈牙利算法的模板中都使用$match[x]==0$来作为有没有匹配过的判断条件,要注意修改。
#pragma GCC optimize (2) #pragma G++ optimize (2) #pragma comment(linker, "/STACK:102400000,102400000") #include<bits/stdc++.h> #include<cstdio> #include<vector> #define rep(i,a,b) for(int i=a;i<=b;i++) #define dep(i,b,a) for(int i=b;i>=a;i--) #define clr(a,b) memset(a,b,sizeof(a)) #define pb push_back #define pii pair<int,int > using namespace std; typedef long long ll; const int inf=0x3f3f3f3f; ll rd() ll x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘)if(ch==‘-‘)f=-1;ch=getchar(); while(ch>=‘0‘&&ch<=‘9‘)x=x*10+ch-‘0‘;ch=getchar(); return x*f; const int maxn=5010; const ll mod=1e9+7; int n,m; vector<int >ve[maxn]; int match[maxn],vis[maxn]; bool dfs(int u) for(auto &v:ve[u]) if(!vis[v]) vis[v]=1; if(match[v]==-1||dfs(match[v])) match[v]=u; return true; return false; struct node int pos,val; arr[maxn]; int k[maxn],num[maxn],ans[maxn]; int main() cin>>n>>m; rep(i,1,n) arr[i].val=rd(); rep(i,1,n) arr[i].pos=rd(); int d; cin>>d; rep(i,1,d) k[i]=rd(); num[k[i]]=1; clr(match,-1); rep(i,1,n) if(!num[i]) ve[arr[i].val].push_back(arr[i].pos); int pos=0; dep(i,d,1) while(1) clr(vis,0); if(dfs(pos)) pos++; else break; ans[i]=pos; ve[arr[k[i]].val].push_back(arr[k[i]].pos); rep(i,1,d) printf("%d\n",ans[i]);
以上是关于codeforces1139E Maximize Mex 二分图匹配的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces 939E Maximize! 离散 三分
Codeforces 939E Maximize! (三分 || 尺取)