您的位置:首页 > 其它

hdu 3729 I'm Telling the Truth(二分图最大匹配)

2013-05-27 17:08 483 查看
好爽!

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

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

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

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

#include<stdio.h>
#include<string.h>
#define N 100005
int mark
,link
;
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: