P2071 座位安排 seat.cpp/c/pas
题目背景
公元二零一四年四月十七日,小明参加了省赛,在一路上,他遇到了许多问题,请你帮他解决。
题目描述
已知车上有N排座位,有N*2个人参加省赛,每排座位只能坐两人,且每个人都有自己想坐的排数,问最多使多少人坐到自己想坐的位置。
输入输出格式
输入格式:
第一行,一个正整数N。
第二行至第N*2+1行,每行两个正整数Si1,Si2,为每个人想坐的排数。
输出格式:
一个非负整数,为最多使得多少人满意。
输入输出样例
说明
对于10%的数据 N≤10
对于30%的数据 N≤50
对于60%的数据 N≤200
对于100%的数据 N≤2000
算法提示:二分图的最大匹配
匈牙利算法,模板图,建图的时候把一个座位拆成两个
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define N 100010 using namespace std; bool vis[N]; int n,m,x,y,tot,ans; int to[N],girl[N],head[N],nextt[N]; int read() { int 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; } int add(int x,int y) { tot++; to[tot]=y; nextt[tot]=head[x]; head[x]=tot; } int find(int x) { for(int i=head[x];i;i=nextt[i]) { int t=to[i]; if(vis[t]) continue; vis[t]=true; if(find(girl[t])||!girl[t]) { girl[t]=x; return 1; } } return 0; } int main() { n=read(); for(int i=1;i<=2*n;i++) { x=read(),y=read(); add(i,x),add(i,n+x); add(i,y),add(i,n+y); } for(int i=1;i<=2*n;i++) { memset(vis,0,sizeof(vis)); ans+=find(i); } printf("%d",ans); return 0; }