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 == ‘\n‘)
                    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\n", R);
    }
    return 0;
}

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

时间: 2024-11-07 08:02:34

POJ 2289 Jamie's Contact Groups(多重匹配+二分)的相关文章

POJ 2289 Jamie&#39;s Contact Groups 二分图多重匹配

题意:n个人,m个组,给出每个人可以分到那些组中,把每个人都分进某组中,问最大组的人数最小为?n<=1e3,m<=500,二分图多重匹配 左边为人 右边为分组 可以多个人对一个组由于要求最大组的最小人数 二分答案x,右边点最多流量为x,判断匹配数是否n即可. #include <iostream> #include <cstdio> #include <cstring> using namespace std; typedef long long ll; t

Poj 2289 Jamie&#39;s Contact Groups (二分+二分图多重匹配)

题目链接: Poj 2289 Jamie's Contact Groups 题目描述: 给出n个人的名单和每个人可以被分到的组,问将n个人分到m个组内,并且人数最多的组人数要尽量少,问人数最多的组有多少人? 解题思路: 二分图多重匹配相对于二分匹配来说不再是节点间的一一对应,而是Xi可以对应多个Yi.所以我们就需要一个限制(Xi最多匹配几个Yi).当Yi需要匹配Xi的时候,Xi的匹配未到上限,直接匹配,否则进行增广路.其实是二分图多重匹配的模板题,再套一个二分枚举最多组的人数就OK咯.下面就上板

POJ - 2289 Jamie&#39;s Contact Groups (二分图多重匹配)

题意:N个人,M个团体.每个人有属于自己的一些团体编号.将每个人分配到自己属于的团体中,问这个人数最多的团体其人数最小值是多少. 分析:一个一对多的二分图匹配,且是最大值最小化问题.二分图的多重匹配建立在匈牙利算法的基础上,令每个Y部的点可匹配多个点,但是规定其上限,超过上限就要在已有的匹配点中寻找增广路.对于X部的点,只要有一个点没有被匹配,那么算法失败.以此二分确定答案,注意二分的姿势... 该题可做模板. #include<iostream> #include<stdio.h>

POJ 2289 Jamie&#39;s Contact Groups (二分+最大流)

题目大意: 有n个人,可以分成m个组,现在给出你每个人可以去的组的编号,求分成的m组中人数最多的组最少可以有多少人. 算法讨论: 首先喷一下这题的输入,太恶心了. 然后说算法:最多的最少,二分的字眼.二分什么,因为我们说的是组的人,所以要对组的流出量进行二分.其余的都连流量为1的边,然后对“小组”点的流出量二分连边,最后跑最大流判断 是否等于N即可.还是蛮简单的. Codes: 1 #include <cstdio> 2 #include <cstring> 3 #include

poj 2289 —— Jamie&#39;s Contact Groups 二分+最大流

原题:http://poj.org/problem?id=2289 #include<cstdio> #include<cstring> #include<string> #include<queue> #include<vector> #include<map> #include<algorithm> #define inf 1e9 using namespace std; const int maxn = 2000;

POJ 2289 Jamie&#39;s Contact Groups

二分答案+网络最大流 #include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<queue> #include<algorithm> using namespace std; int N,M; const int maxn = 2000 + 10; const int INF = 0x7FFFFFFF; struct Edge { int

M - Jamie&#39;s Contact Groups - poj 2289(二分图多重匹配)

题意:某个人通讯录有很多人,现在他想把这个人分组,给的数据是可以把这个人分在那些组里面,现在他想知道分组后,人最多的那个组至少有多少人. 分析:因为没有给组限制有多少人,可以使用二分求出来最小的那个,感觉还是挺暴力的.....不过时间确实很少 500多ms ******************************************************************** #include<stdio.h>#include<string.h>#include&l

Jamie&#39;s Contact Groups(二分图多重匹配+二分)(网络流)

Jamie's Contact Groups Time Limit:7000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 2289 Description Jamie is a very popular girl and has quite a lot of friends, so she always keeps a very long contact list

POJ2289:Jamie&#39;s Contact Groups(二分+二分图多重匹配)

Jamie's Contact Groups Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 125536/65536 K (Java/Others) 题目链接:http://poj.org/problem?id=2289 Description: Jamie is a very popular girl and has quite a lot of friends, so she always keeps a very long