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;

}


 

 

你可能感兴趣的:(HDU)