洛谷P2071 座位安排
题目背景
公元二零一四年四月十七日,小明参加了省赛,在一路上,他遇到了许多问题,请你帮他解决。
题目描述
已知车上有N排座位,有N*2个人参加省赛,每排座位只能坐两人,且每个人都有自己想坐的排数,问最多使多少人坐到自己想坐的位置。
输入格式
第一行,一个正整数N。
第二行至第N*2+1行,每行两个正整数Si1,Si2,为每个人想坐的排数。
输出格式
一个非负整数,为最多使得多少人满意。
题解:显然可以点可以分为两个集合,左集合是人,右集合是座位,把每一列座位拆成两个点,然后想让最多人满意,
就把当前人和他满意的排数的两个点连一条边,跑一个二分图最大匹配即可。
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> using namespace std; struct node { int ed,nxt; }; node edge[4005*16]; int n,cnt,first[4005],ans; bool used[4005*2]; int match[4005*2]; inline void add_edge(int s,int e) { cnt++; edge[cnt].ed=e; edge[cnt].nxt=first[s]; first[s]=cnt; return; } inline bool dfs(int k) { for(int i=first[k];i;i=edge[i].nxt) { int ed=edge[i].ed; if(!used[ed]) { used[ed]=true; if(!match[ed]||dfs(match[ed])) { match[ed]=k; return true; } } } return false; } int main() { scanf("%d",&n); for(int i=1;i<=2*n;i++) { int s1,s2; scanf("%d%d",&s1,&s2); add_edge(i,s1*2-1); add_edge(i,s1*2); add_edge(i,s2*2-1); add_edge(i,s2*2); } for(int i=1;i<=2*n;i++) { memset(used,false,sizeof(used)); if(dfs(i)) ans++; } printf("%d",ans); return 0; }