POJ 2289 Jamie's Contact Groups(多重匹配+二分)

题意:
Jamie有很多联系人,但是很不方便管理,他想把这些联系人分成组,已知这些联系人可以被分到哪个组中去,而且要求每个组的联系人上限最小,即有一整数k,使每个组的联系人数都不大于k,问这个k最小是多少?
题目分析:
多重匹配,二分枚举所有极限值。
多重匹配如何匹配?
假如我们有两个集合X, Y 但是呢 Y可以匹配多个X, 这个时候我们需要给这个匹配设置一个极限值。比如Y可以匹配三个X。 假如匹配的值不到三个X我们就将他们匹配,
直到到达极限值为止。在这里Y要保存所有的与之匹配的X,若是匹配值满了,进行Find()匹配就行了。
 
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<vector>
#include<queue>
#include<cmath>
using namespace std;
#define INF 0x3fffffff
#define maxn 1505
int n, m;
bool G[maxn][maxn], vis[maxn];
vector<vector<int> >Group;

bool Find(int u,int limt)
{
    for(int i=0; i<m; i++)
    {
        if(G[u][i] && !vis[i])
        {
            vis[i] = true;
            if( Group[i].size() < limt )
            {
                Group[i].push_back(u);
                return true;
            }
            for(int j=0; j < Group[i].size(); j++)
            {
                if( Find(Group[i][j], limt) )
                {
                    Group[i].erase(Group[i].begin()+j);
                    Group[i].push_back(u);
                    return true;
                }
            }
        }
    }
    return false;
}


bool solve(int limt)
{
    int num = 0;
    Group.clear();
    Group.resize(m+1);
    for(int i=0; i<n; i++)
    {
        memset(vis, false, sizeof(vis));
        if(Find(i, limt) )
            num ++;
    }
    return num == n;
}

int main()
{
    int a;
    char ch;
    while(scanf("%d %d",&n, &m), n+m)
    {
        memset(G, false, sizeof(G));
        for(int i=0; i<n; i++)
        {
            scanf("%*s");
            while(1)
            {
               // getchar();
                scanf("%d%c",&a, &ch);
                G[i][a] = true;
                if(ch == '
')
                    break;
            }
        }
        int L = 0, R = n;
        while(L < R)
        {
            int mid = (L + R) / 2;
            if( solve(mid) )
                R = mid;
            else
                L = mid + 1;
        }
        printf("%d
", R);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/chenchengxun/p/4718609.html