比赛 HAOI2009 模拟试题2 评测结果 AAAWWTTTTT
题目名称 棋盘上的问题 最终得分 30
用户昵称 zqzas 运行时间 0.000 s
代码语言 C++ 内存使用 0.00 MiB
提交时间 2009-04-22 11:23:46
显示代码纯文本
#include <iostream>

#define MAXV 200010
#define MAXE 600010

struct Edge{
	int a,b,next;
};

int v,e,c,maxm,ans,vis[MAXV],match[MAXV],fore[MAXV];
struct Edge edge[MAXE];
bool disable[MAXE];


bool aug(int x)
{
	int i,y;
	vis[x]=c;
	for (i=fore[x];i!=0;i=edge[i].next)
	{
		y=edge[i].b;
		if (vis[match[y]]!=c)
			if (match[y]==0 || aug(match[y]))
			{
				match[y]=x;
				return true;
			}
	}
	return false;
}

bool aug2(int x)
{
	int i,y;
	vis[x]=c;
	for (i=fore[x];i!=0;i=edge[i].next)
	{
		if (disable[i]) 
			continue;
		y=edge[i].b;
		if (vis[match[y]]!=c)
			if (match[y]==0 || aug2(match[y]))
			{
				return true;
			}
	}
	return false;
}

void run()
{
	int i;
	//hungary
	for (i=1;i<=v;i++)
	{
		c++;
		if (aug(i))
			maxm++;
	}
	for (i=1;i<=e;i++)
		if (match[edge[i].b]==edge[i].a)
		{
			match[edge[i].b]=0;
			disable[i]=true;
			c++;
			if (aug2(edge[i].a))
				ans++;
			disable[i]=false;
			match[edge[i].b]=edge[i].a;
		}
	ans=e-(maxm-ans);
}

void addEdge(int i,int a,int b)
{
	edge[i].a=a;
	edge[i].b=b;
	edge[i].next=fore[a];
	fore[a]=i;
}
void ini()
{
	int i,a,b;
	scanf("%d%d",&v,&e);
	for (i=1;i<=e;i++)
	{
		scanf("%d%d",&a,&b);
		addEdge(i,a,b);
	}
}

int main()
{
	freopen("board.in","r",stdin);
	freopen("board.out","w",stdout);
	ini();
	run();
	printf("%d",ans);
	return 0;
}