记录编号 270636 评测结果 AAAAAAAAA
题目名称 [USACO 4.2] 完美的牛栏 最终得分 100
用户昵称 GravatarHzoi_ 是否通过 通过
代码语言 C++ 运行时间 0.000 s
提交时间 2016-06-15 09:34:27 内存使用 0.00 MiB
显示代码纯文本
//求二分图最大匹配的匈牙利算法
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=210;
struct edge{
	int to;
	edge* prev;
	edge():to(0),prev(NULL){}
}ee[2*maxn*maxn];
void insert(int,int);
bool path(int);
int maxmatch();
int len=0;
edge* last[maxn]={NULL};
int na,nb;//a集合和b集合中顶点的个数
int ca[maxn]={0},cb[maxn]={0};//用来记录匹配的元素是哪个
bool vis[maxn];
int x,y;
inline int MAIN(){
#define MINE
#ifdef MINE
	freopen("stall4.in","r",stdin);
	freopen("stall4.out","w",stdout);
#endif
	scanf("%d%d",&na,&nb);
	for(int i=1;i<=na;i++){
		scanf("%d",&x);
		for(int j=0;j<x;j++){
			scanf("%d",&y);
			insert(i,y);
		}
	}
	printf("%d",maxmatch());
	return 0;
}
inline void insert(int x,int y){
	ee[len].to=y;
	ee[len].prev=last[x];
	last[x]=&ee[len++];
}
inline bool path(int x){//找增广路
	for(edge* e=last[x];e;e=e->prev){
		int y=e->to;
		if(!vis[y]){
			vis[y]=true;
			if(!cb[y]||path(cb[y])){
				//如果y集合中的v元素没有匹配或者是v已经匹配,
				//但是从cy[v]中能够找到一条增广路
				ca[x]=y;
				cb[y]=x;//找到增广路,修改匹配M
				return true;
			}
		}
	}
	return false;
}
inline int maxmatch(){//求最大匹配
	int result=0;
	for(int i=1;i<=na;i++){
		if(!ca[i]){//还没被匹配
			memset(vis,0,sizeof(vis));
			result+=path(i);//以i为起点开始查找增广路,若返回true,匹配数+1
		}
	}
	return result;
}
int haha=MAIN();
int main(){;}