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; }