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

来源:互联网 发布:linux如何给文件夹改名 编辑:程序博客网 时间:2024/06/06 04:55
//hdu 3729//对于区间而言,只能选择固定的人数,且每个排名只能有一个人,很显然左边人数,右边区间进行二分匹配。//对于字典序最大的匹配,我们枚举人的时候,从n->1,这样保证尽可能选后面。#include<cstdio>#include<cstring>#include<iostream>using namespace::std;const int INF=0x7fffffff;const int N=100,M=100010;int g[N][N];struct node{    int x,y;}node[N];int re[N];struct Hungary{    int used[M],line[M];    void init(){        memset(line,-1,sizeof(line));    }    bool find(int u){        for(int i=node[u].x;i<=node[u].y;i++){            if(!used[i]){                used[i]=true;                if(line[i]==-1||find(line[i])){                    line[i]=u;                    re[u]=i;                    return 1;                }            }        }        return 0;    }    int Max_match(int n){        int all=0;        for(int i=n;i>=1;i--){            memset(used,0,sizeof(used));            if(find(i))all+=1;        }        return all;    }};Hungary huy;int main(){    int T;    int n,m,u,v;    scanf("%d",&T);    while(T--){        memset(re,0,sizeof(re));        scanf("%d",&n);        for(int i=1;i<=n;i++)            scanf("%d%d",&node[i].x,&node[i].y);        huy.init();        int sum=huy.Max_match(n);        printf("%d\n",sum);        for(int i=1;i<=n;i++){            if(re[i]>0){                sum--;                if(sum!=0)printf("%d ",i);                else printf("%d\n",i);            }        }    }    return 0;}

0 0
原创粉丝点击