hdu 3729(二分图最大匹配)

好爽!

我在百度搜索hdu 二分图最大匹配,百度给出的第一个结果就是这道题。刚开始看这道题的时候,以我对二分图匹配非常浅薄的理解,我怎么也想不明白这道题怎么就二分图最大匹配了。

后来想明白了,对于第i个人,我们知道他的合法区间[a[i].x,a[i].y]。首先我们将其和他合法区间内的第一个值进行匹配,如果有后来的人需要和这个值匹配的时候,我们就让这个人和别的合法区间内的值进行匹配,如果匹配成功,就将他之前所匹配的值让出来给后来的人,如果匹配失败,就继续占着这个位置。

这里很重要的一点是,对于一个值的匹配,我们遵守先来后到的原则,对于先来的已经匹配成功的人,如果没有找到其他符合条件的位置,这个人占的位置是绝对不能让出来的。这点很关键,因为题目还要求输出所有可能性中字典序最大的。

感觉做完这道题对二分图最大匹配理解深刻了好多,之前就是看懂了模板而已。而且还是1A。爽!

#include<stdio.h>
#include<string.h>
#define N 100005
int mark[N],link[N];
struct node
{
	int x,y;
}a[105];
int ss[105];
int n;
int dfs(int t)
{
	int i;
	for(i=a[t].x;i<=a[t].y;i++)
	{
		if(mark[i]==-1)
		{
			mark[i]=1;
			if(link[i]==-1||dfs(link[i]))
			{
				link[i]=t;
				ss[t]=1;
				return 1;
			}
		}
	}
	return 0;
}
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&n);
		int i;
		for(i=1;i<=n;i++)
			scanf("%d%d",&a[i].x,&a[i].y);
		memset(link,-1,sizeof(link));
		memset(ss,0,sizeof(ss));
		int sum;
		sum=0;
		for(i=n;i>=1;i--)
		{
			memset(mark,-1,sizeof(mark));
			if(dfs(i))
				sum++;
		}
		printf("%d\n",sum);
		for(i=1;i<=n-1;i++)
		{
			if(ss[i]==1)
				printf("%d ",i);
		}
		printf("%d\n",i);
	}
	return 0;
}


原文地址:https://www.cnblogs.com/javawebsoa/p/3102220.html