Steady Cow Assignment POJ - 3189

来源:互联网 发布:淘宝卖家不评论吗 编辑:程序博客网 时间:2024/05/19 12:25

题目连接点这里

建图转化为二分图之后,我们可以二分范围,然后枚举起点,转化为判断性问题

#include<iostream>#include<stdio.h>#include<queue>#include<algorithm>#include<string.h>#define MX 2222#define INF 0x3f3f3f3f#define mem(x,y) memset(x,y,sizeof(x))#define FIN freopen("input.txt","r",stdin)using namespace std;int n,m;int head[MX],rear;struct{    int to,nxt;    int val;} edge[1111*MX];void edge_init(){    mem(head,-1);    rear=0;}void edge_add(int a,int b,int c){    edge[rear].to=b;    edge[rear].val=c;    edge[rear].nxt=head[a];    head[a]=rear++;}bool vis[MX];int match[MX][1111];int mcnt[MX];int limit[MX];bool hungarian_dfs(int u,int l,int r){    for(int i=head[u]; ~i; i=edge[i].nxt)    {        if(edge[i].val<=r&&edge[i].val>=l)        {            int v=edge[i].to;            if(vis[v]) continue;            vis[v]=1;            if(mcnt[v]<limit[v-n])            {                match[v][++mcnt[v]]=u;                return 1;            }            for(int j=1; j<=limit[v-n]; j++)                if(hungarian_dfs(match[v][j],l,r))                {                    match[v][j]=u;                    return 1;                }        }    }    return 0;}int hungarian(int l,int r){    //cout<<l<<" "<<r<<endl;    mem(mcnt,0);    int ret=0;    for(int i=1; i<=n; i++)    {        mem(vis,0);        if(hungarian_dfs(i,l,r)==0) return 0;//小优化,如果不存在增广路,直接跳出,因为,此题中二分图必为完备匹配    }    return 1;}bool check(int x){    //cout<<x<<endl;    for(int i=1; i+x-1<=m+n; i++)    {        if(hungarian(i,i+x-1))return 1;    }    return 0;}int erfeng(int l,int r){    int mid;    while(l<r)    {        mid=((l+r)>>1);        if(check(mid)) r=mid;        else l=mid+1;        //cout<<l<<" "<<r<<endl;    }    return l;}int main(){    FIN;    while(scanf("%d%d",&n,&m)==2)    {        edge_init();        for(int i=1,x; i<=n; i++)        {            for(int j=1; j<=m; j++)            {                scanf("%d",&x);                edge_add(i,n+x,j);                edge_add(n+x,i,j);            }        }        for(int i=1; i<=m; i++) scanf("%d",&limit[i]);        printf("%d\n",erfeng(1,m));    }    return 0;}


0 0
原创粉丝点击