Jamie's Contact Groups---hdu1669--poj2289(多重匹配)

题目链接

题意:Jamie有很多联系人,但是很不方便管理,他想把这些联系人分成组,已知这些联系人可以被分到哪个组中去,而且要求每个组的联系人上限最小,即有一整数k,使每个组的联系人数都不大于k,问这个k最小是多

少?

一对多的二分图的多重匹配。二分图的多重匹配算法的实现类似于匈牙利算法,对于集合x中的元素xi,找到一个与其相连的元素yi后,检查匈牙利算法的两个条件是否成立,若yi未被匹配,则将

xi,yi匹配。否则,如果与yi匹配的元素已经达到上限,那么在所有与yi匹配的元素中选择一个元素,检查是否能找到一条增广路径,如果能,则让出位置,让xi与yi匹配。

二分求出limit,知道找到可以构成多重匹配的最小限制limit,在main函数中二分搜索。

#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
using namespace std;
#define N 1010
int vis[N], maps[N][N], ans, n, m;
struct node
{
    int cnt;///和yi相匹配的个数;
    int k[N];///和yi相匹配的x的集合;
}Linky[N];

bool Find(int u, int limit)
{
    for(int i=1; i<=m; i++)
    {
        if(!vis[i] && maps[u][i])
        {
            vis[i] = 1;
            if(Linky[i].cnt < limit)
            {
                Linky[i].k[ Linky[i].cnt++ ] = u;
                return true;
            }
            for(int j=0; j<Linky[i].cnt; j++)
            {
                if(Find( Linky[i].k[j], limit ))
                {
                    Linky[i].k[j] = u;
                    return true;
                }
            }
        }
    }
    return false;
}

bool xyl(int limit)///匈牙利算法;
{
    memset(Linky, 0, sizeof(Linky));
    for(int i=1; i<=n; i++)
    {
        memset(vis, 0, sizeof(vis));
        if(!Find(i, limit))///当前的limit让i没有匹配,所以不能用limit;
            return false;
    }
    return true;
}

int main()
{
    int x;
    char s[20], ch;
    while(scanf("%d %d", &n, &m), m+n)
    {
        memset(maps, 0, sizeof(maps));
        for(int i=1; i<=n; i++)
        {
            scanf("%s", s);
            while(1)
            {
                scanf("%d%c", &x, &ch);
                maps[i][x+1] = 1;
                if(ch == ‘\n‘)
                    break;
            }
        }
        int L = 1, R = n;
        ans = n;
        while(L <= R)
        {
            int mid = (L+R)/2;
            if(xyl(mid))///如果当前mid满足题意;
            {
                R = mid-1;
                ans = mid;
            }
            else
                L = mid+1;
        }
        printf("%d\n", ans);
    }
    return 0;
}

Jamie's Contact Groups---hdu1669--poj2289(多重匹配)

时间: 2024-10-09 21:46:54

Jamie's Contact Groups---hdu1669--poj2289(多重匹配)的相关文章

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

题意: 给定一个规模为n的名单,要将名单中的人归到m个组中,给出每个人可能的分组号,需要确定一种分配方案,使得最大规模的组最小. 思路: 二分图多重匹配 如果所到的组没满,就去那个组 如果满了,就从那个组里踢出一个 如果能踢出来,就把那个踢出来,把当前的放进去 如果所有能到的组都踢不出来,就不对了 至于那个最大规模的具体值,二分一下就OK了 /* *********************************************** Author :devil Created Time

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

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

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

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

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

POJ 2289--Jamie&#39;s Contact Groups【二分图多重匹配问题 &amp;&amp;二分查找最大值的最小化 &amp;&amp; 最大流】

Jamie's Contact Groups Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 6902   Accepted: 2261 Description Jamie is a very popular girl and has quite a lot of friends, so she always keeps a very long contact list in her cell phone. The con

POJ--2289--Jamie&#39;s Contact Groups【二分图多重匹配+二分答案】

链接:http://poj.org/problem?id=2289 题意:有n个人,m个分组,每个人可以分配到一些组别,问如何分能使得人数最多的组别人数最少. 思路:这道题二分+网络流也可以做,我这里是二分图多重匹配的做法.因为一个组别是一对多的关系,所以是多重匹配,我们二分多重匹配的限制,得到最小的限制可使二分图匹配,这个限制就是答案. 网上找的模板 #include<cstring> #include<string> #include<fstream> #inclu

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

多重匹配:一对多的二分图的多重匹配.二分图的多重匹配算法的实现类似于匈牙利算法,对于集合X中的元素xi,找到一个与其相连的元素yi后,检查匈牙利算法的两个条件是否成立,若yi未被匹配,则将 xi,yi匹配.否则,如果与yi匹配的元素已经达到上限,那么在所有与yi匹配的元素中选择一个元素,检查是否能找到一条增广路径,如果能,则让出位置,让xi与yi匹配. match[i][j]表示X集合中的Xi点与y集合中的j个点相连接(一对多) #include<cstdio> #include<ios

POJ2289 Jamie&#39;s Contact Groups —— 二分图多重匹配/最大流 + 二分

题目链接:https://vjudge.net/problem/POJ-2289 Jamie's Contact Groups Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 8147   Accepted: 2736 Description Jamie is a very popular girl and has quite a lot of friends, so she always keeps a very lon

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

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