• poj3189二分图多重匹配


    题意:有一些牛和牛棚(有容量),每头牛对牛棚有喜好程度,要求每头牛都有一个棚子的情况下,找最小的喜好程度之差

    题解:题意是真的恶心,wa了好久才发现没读懂,一直以为输入 的是排名,其实是牛棚标号,从1到m。用最大流一直tle,无奈还是用匈牙利算法,对于匈牙利算法求解二分图多重匹配,可以用一个容量数组来操作,如果容量没满,那么直接放进来,否则就遍历一遍,看是否有可能找到增广路,这题是二分差值,然后通过遍历找满足条件的最小结果。

    #include<map>
    #include<set>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<vector>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pii pair<int,int>
    #define C 0.5772156649
    #define pi acos(-1.0)
    #define ll long long
    #define mod 20090717
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    
    using namespace std;
    
    const double g=10.0,eps=1e-12;
    const int N=3000+10,maxn=20000+10,inf=0x3f3f3f3f;
    
    int ra[N][30],c[30],num[30];
    bool vis[30];
    struct edge{
        int to,Next;
    }e[maxn<<2];
    int n,m,ans[30][N];
    int cnt,head[N];
    void add(int u,int v)
    {
       // cout<<u<<" "<<v<<endl;
        e[cnt].to=v;
        e[cnt].Next=head[u];
        head[u]=cnt++;
    }
    bool match(int x)
    {
        for(int i=head[x];~i;i=e[i].Next)
        {
            int y=e[i].to;
            if(vis[y])continue;
            vis[y]=1;
            if(num[y]<c[y])
            {
                ans[y][++num[y]]=x;
                return 1;
            }
            else
            {
                for(int j=1;j<=c[y];j++)
                {
                    if(match(ans[y][j]))
                    {
                        ans[y][j]=x;
                        return 1;
                    }
                }
            }
        }
        return 0;
    }
    void init()
    {
        cnt=0;
        for(int i=1;i<=n;i++)head[i]=-1;
        for(int i=1;i<=m;i++)
            for(int j=1;j<=n;j++)
                ans[i][j]=0;
        for(int i=1;i<=m;i++)num[i]=0;
    }
    bool isok(int x)
    {
        for(int k=0; k+x<=m; k++)
        {
            init();
            for(int i=1; i<=n; i++)
                for(int j=k+1; j<=k+x; j++)
                    add(i,ra[i][j]);
            int res=0;
            for(int i=1; i<=n; i++)
            {
                for(int j=1; j<=m; j++)vis[j]=0;
                if(match(i))res++;
            }
            if(res==n)
            {
                return 1;
            }
        }
        return 0;
    }
    int main()
    {
        /*ios::sync_with_stdio(false);
        cin.tie(0);*/
        while(~scanf("%d%d",&n,&m))
        {
            for(int i=1; i<=n; i++)
                for(int j=1; j<=m; j++)
                    scanf("%d",&ra[i][j]);
            for(int i=1; i<=m; i++)scanf("%d",&c[i]);
            int l=0,r=m+1;
            while(r-l>1)
            {
                int mid=(l+r)/2;
                if(isok(mid))r=mid;
                else l=mid;
            }
            printf("%d
    ",r);
        }
        return 0;
    }
    /********************
    6 6
    2 3 4 5 6 1
    3 6 4 5 1 2
    2 6 4 5 1 3
    3 6 2 5 1 4
    1 3 4 2 6 5
    2 3 4 5 1 6
    2 2 2 2 2 2
    ********************/
    View Code
  • 相关阅读:
    云计算设计模式(十一)——健康端点监控模式
    大数据R语言简析
    git查看/修改 用户名和邮箱
    MySQL查询和修改auto_increment的方法
    git 配置用户名和邮箱
    discuz安装小云app
    二维码转化为链接
    discuz更换域名,登录不了解决
    数据结构很重要
    C++ vector错误(1)
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/7837763.html
Copyright © 2020-2023  润新知