[洛谷P2071] 座位安排
题目链接:###
题目分析:###
二分图,人为左部点,座位为右部点,由于每个座位可以坐两个人,所以把每个座位拆成两个点\(i\)和\(i+n\),如果一个人想去这个座位则向这两个点连边,跑匈牙利即可。
代码:###
#include<bits/stdc++.h>
#define N (100000+5)
using namespace std;
inline int read(){
int cnt=0,f=1;char c;
c=getchar();
while(!isdigit(c)){
if(c=='-')f=-f;
c=getchar();
}
while(isdigit(c)){
cnt=cnt*10+c-'0';
c=getchar();
}
return cnt*f;
}
int n,match[N],x,y,nxt[N],first[N],to[N],tot,ans,res;
bool vis[N];
void add(int x,int y){
nxt[++tot]=first[x];
first[x]=tot;
to[tot]=y;
}
int find(int u){
for(register int i=first[u];i;i=nxt[i]) {
int v=to[i];
if(vis[v]) continue;
else {
vis[v]=1;
if(match[v]==-1||find(match[v])){
match[v]=u;
return 1;
}
}
}
return 0;
}
int hungary(){
for(register int i=1;i<=2*n;i++) match[i]=-1;
for(register int i=1;i<=2*n;i++) {
for(register int j=1;j<=2*n;j++) vis[j]=0;
ans+=find(i);
}
return ans;
}
int main(){
n=read();
for(register int i=1;i<=2*n;i++){
x=read();y=read();
add(i,x);add(i,x+n);
add(i,y);add(i,y+n);
}
int res=hungary();
printf("%d",res);
return 0;
}