zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    有关人工智能的假设
    遥感数据下载
    envi几何校正
    2440裸 Delay(); 和 while(!(rUTRSTAT0 &amp; 0x2)); 问题
    hadoop排序组合键的使用情况
    ASP.NET——RequiredFieldValidator控制和ValidationSummary控制
    TFTP server组态
    Notification(一个)——使用演示样本的基础知识
    学习计划,我希望这不会虎头蛇尾
    只有有lua编译能力不足200K代码吧?NO! Python 有可能。
  • 原文地址:https://www.cnblogs.com/d-e-v-i-l/p/5502614.html
Copyright © 2011-2022 走看看