洛谷P2071 座位安排

一个比较裸的二分图最大匹配

不会的先去学习一下,P3386 【模板】二分图最大匹配

不难发现是把每个人与希望坐的排数建一条边,但是因为一排有两个座位,所以就把每一排的两个座位拆成两个点,分别建边,再求最大匹配即可。

我把第 \(x\) 排的两个座位分别设为 \(x\)\(x+i\),然后直接向这两个点建边。

#include<iostream>
#include<cstdio>
#define N 4010
#define M 16010

using namespace std;

int n;
struct edge
{
	int to,nxt;
}e[M];
int head[N],tot;

void add(int x,int y)	//前向星建边 
{
	e[++tot].to=y;
	e[tot].nxt=head[x];
	head[x]=tot;
}

int tim,t[N],match[N];	//tim:时间戳,后边就不用memset了,直接判断t[v]==tim 

bool dfs(int x)
{
	for(int i=head[x]; i; i=e[i].nxt)
	{
		int v=e[i].to;
		if(t[v]==tim) continue;
		t[v]=tim;
		if(!match[v]||dfs(match[v]))
		{
			match[v]=x;
			return true;
		}
	}
	return false;
}

int main()
{
	scanf("%d",&n);
	for(int i=1; i<=n*2; i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		add(i,x);	//x排第1个座位
		add(i,n+x);	//x排第2个座位 
		add(i,y);
		add(i,n+y);
	}
	int ans=0;
	for(int i=1; i<=n*2; i++)
	{
		tim++;	//时间戳+1 
		if(dfs(i)) ans++;
	}
	printf("%d\n",ans);
	return 0;
}
posted @ 2020-06-17 22:36  Acestar  阅读(119)  评论(0编辑  收藏  举报