1:思路:(匈牙利算法(二分图最大匹配))
一个比较裸的二分图最大匹配。
2:几乎模板,不同的就是建边的问题:(解决方案)
不难发现是把每个人与希望坐的排数建一条边,但是因为一排有两个座位,所以就把每一排的两个座位拆成两个点,分别建边,再求最大匹配即可。
我把第 x 排的两个座位分别设为 x 和 x+i,然后直接向这两个点建边。
3:ACcode:
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=8e3+10,M=1e5+10;
int h[N],e[M],ne[M],idx;
bool vis[N];
int res,match[N],n,m,ans[N];
void add(int a,int b) {
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
bool find(int t) {
for(int i=h[t]; i!=-1; i=ne[i]) {
int j=e[i];
if(!vis[j]) {
vis[j]=true;
if(match[j]==0||find(match[j])) {
match[j]=t,ans[t]=j;
return true;
}
}
}
return false;
}
void solve() {
cin>>n;
memset(h,-1,sizeof h);
for(int i=1; i<=2*n; i++) {
int a,b;
cin>>a>>b;
add(a,i),add(a+n,i);//每排两个座位
add(b,i),add(b+n,i);
}
for(int i=1; i<=2*n; i++) {
memset(vis,false,sizeof vis);
if(find(i)) res++;
}
cout<<res<<"\n";
}
signed main() {
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int tt=1;
//cin>>tt;
while(tt--) solve();
return 0;
}
//3
over~