【最大二分匹配匈牙利算法】hdu 3729

来源:互联网 发布:齐博cms模板 编辑:程序博客网 时间:2024/06/03 12:49

匈牙利算法的match数组已经是记录对应的匹配,赞!

有个技巧,因为要输出字典序最大,按他的说法,就是第一个尽量大,所以应该从n向前找,最后sort一下。本人有点懒,匈牙利算法代模板

#include <vector>#include <list>#include <map>#include <set>#include <queue>#include <string>#include <deque>#include <stack>#include <algorithm>#include <iostream>#include <iomanip>#include <cstdio>#include <cmath>#include <cstdlib>#include <limits.h>#include <time.h>#include <string.h>using namespace std;int lowbit(int t){return t&(-t);}int countbit(int t){return (t==0)?0:(1+countbit(t&(t-1)));}int gcd(int a,int b){return (b==0)?a:gcd(b,a%b);}#define LL long long#define PI acos(-1.0)#define Max INT_MAX#define Min INT_MIN#define eps 1e-8#define FRE freopen("a.txt","r",stdin)#define N  100001//MAXN表示X集合中点的最大个数,MAXM表示Y集合中点的最大个数//n表示X集合中点的实际个数,m表示Y集合中点的实际个数int max(int a,int b){return a>b?a:b;}int min(int a,int b){return a>b?b:a;}bool g[61][N],vis[N];   //g[i][j]=true说明i到j有一条边int match[N];   //与Y中的点匹配的点标识int minm,maxm;bool SearchPath(int s){    for(int i=minm;i<=maxm;i++){        if(g[s][i] && !vis[i]){   //如果从s到i有边且Y中的i点没有被访问过            vis[i]=true;            if(match[i]==0 || SearchPath(match[i])){  //查找可增广路并更新match数组                match[i]=s;                return true;            }        }    }    return false;}int ans[N];int main(){    int ca;    scanf("%d",&ca);    while(ca--){        int n;        scanf("%d",&n);        int i,j;        minm=Max;        maxm=0;        memset(g,0,sizeof(g));        for(i=1;i<=n;i++){            int a,b;            scanf("%d%d",&a,&b);            minm=min(minm , a);            maxm=max(maxm , b);            for(j=a;j<=b;j++){                g[i][j]=1;            }        }        memset(match,0,sizeof(match));        int sum=0;        for(i=n;i>=1;i--){            memset(vis,0,sizeof(vis));            if(SearchPath(i))sum++;        }        int cnt=0;        for(i=minm;i<=maxm;i++)        if(match[i])        ans[cnt++]=match[i];        sort(ans,ans+cnt);        printf("%d\n",sum);        printf("%d",ans[0]);        for(i=1;i<cnt;i++)printf(" %d",ans[i]);        puts("");    }    return 0;}