• POJ2289 Jamie's Contact Groups(二分图多重匹配)


    题意:

    给定一个规模为n的名单,要将名单中的人归到m个组中,给出每个人可能的分组号,需要确定一种分配方案,使得最大规模的组最小。

    思路:

    二分图多重匹配

    如果所到的组没满,就去那个组

    如果满了,就从那个组里踢出一个

    如果能踢出来,就把那个踢出来,把当前的放进去

    如果所有能到的组都踢不出来,就不对了

    至于那个最大规模的具体值,二分一下就OK了

    /* ***********************************************
    Author        :devil
    Created Time  :2016/5/17 17:56:52
    ************************************************ */
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <cmath>
    #include <stdlib.h>
    using namespace std;
    const int N=1010;
    const int M=510;
    int n,m,mid,x;
    char s[20];
    bool vis[M];
    vector<int>eg[N],isin[M];
    bool Find(int u)
    {
        for(int i=0;i<eg[u].size();i++)
        {
            int v=eg[u][i];
            if(!vis[v])
            {
                vis[v]=1;
                if(isin[v].size()<mid)
                {
                    isin[v].push_back(u);
                    return 1;
                }
                for(int j=0;j<isin[v].size();j++)
                {
                    if(Find(isin[v][j]))
                    {
                        isin[v][j]=u;
                        return 1;
                    }
                }
            }
        }
        return 0;
    }
    bool maxmatch()
    {
        for(int i=0;i<m;i++)
            isin[i].clear();
        for(int i=0;i<n;i++)
        {
            memset(vis,0,sizeof(vis));
            if(!Find(i)) return 0;
        }
        return 1;
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        while(~scanf("%d%d",&n,&m)&&(n+m))
        {
            for(int i=0;i<n;i++)
                eg[i].clear();
            for(int i=0;i<n;i++)
            {
                scanf("%s",s);
                while(scanf("%d",&x)==1)
                {
                    eg[i].push_back(x);
                    if(getchar()=='
    ') break;
                }
            }
            int l=0,r=n;
            while(l<r)
            {
                mid=(l+r)>>1;
                if(maxmatch()) r=mid;
                else l=mid+1;
            }
            printf("%d
    ",r);
        }
        return 0;
    }
  • 相关阅读:
    设计模式总结——程序猿武功秘籍(下一个)
    easyui datagrid显示进度条控制操作
    使用CountDownLatch和CyclicBarrier处理并发线程
    人类探索地外文明显著取得的进展
    Linux 启动过程的详细解释
    不会跳回到微博认定申请书
    unix域套接字UDP网络编程
    VS SQL 出现%CommonDir%dte80a.olb 该解决方案
    数据仓库与数据挖掘的一些基本概念
    CheckBoxPreference组件
  • 原文地址:https://www.cnblogs.com/d-e-v-i-l/p/5502614.html
Copyright © 2020-2023  润新知