Codeforces Round #548 (Div. 2) E 二分圖匹配(新坑) or 網絡流 + 反向處理
阿新 • • 發佈:2019-03-31
-- cin problem fine max href fin names i++
https://codeforces.com/contest/1139/problem/E
題意
有n個學生,m個社團,每個學生有一個\(p_i\)值,然後每個學生屬於\(c_i\)社團,
有d天,每天首先隨機去除一個人,然後再從每個社團挑選一個學生(假如社團沒有學生就跳過這個社團),使得這些學生組成的集合的mex值最大,輸入每天的mex值
題解
- 假如這道題發現是二分圖匹配就很好做
- 左邊用\(p_i\)建點,右邊用\(c_i\)建點,\(p_i\)從小到達和源點連邊,然後跑個二分圖匹配or最大流,直到沒有新的匹配,就在中間加邊
- 倒著處理,每次加邊進去(技巧)
代碼
#include<bits/stdc++.h> #define MAXN 5005 using namespace std; int n,m,i,j,link[MAXN],p[MAXN],c[MAXN],d,k[MAXN],vi[MAXN],ans[MAXN]; int del[MAXN]; vector<int>mp[MAXN]; int match(int u){ for(auto i:mp[u]){ if(!vi[i]){ vi[i]=1; if(link[i]==-1||match(link[i])){ link[i]=u; vi[i]=0; return 1; } vi[i]=0; } } return 0; } int main(){ cin>>n>>m; memset(link,-1,sizeof(link)); for(i=1;i<=n;i++)cin>>p[i]; for(i=1;i<=n;i++)cin>>c[i]; cin>>d; for(i=1;i<=d;i++){cin>>k[i];del[k[i]]=1;} for(i=1;i<=n;i++)if(!del[i]){mp[p[i]].push_back(c[i]);} j=0; for(i=d;i>=1;i--){ int id=k[i]; for(;j<5000;j++){ //memset(vi,0,m*sizeof(int)); if(!match(j))break; } ans[i]=j; mp[p[id]].push_back(c[id]); } for(i=1;i<=d;i++)cout<<ans[i]<<endl; }
Codeforces Round #548 (Div. 2) E 二分圖匹配(新坑) or 網絡流 + 反向處理