HDU 1669 二分图多重匹配+二分

Jamie‘s Contact Groups

Time Limit: 15000/7000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 747    Accepted Submission(s): 303

Problem 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 contact list has become so long that it often takes a long time for her to browse through the whole list to find a friend‘s number. As Jamie‘s best friend and a programming genius, you suggest that she group the contact list and minimize the size of the largest group, so that it will be easier for her to search for a friend‘s number among the groups. Jamie takes your advice and gives you her entire contact list containing her friends‘ names, the number of groups she wishes to have and what groups every friend could belong to. Your task is to write a program that takes the list and organizes it into groups such that each friend appears in only one of those groups and the size of the largest group is minimized.

Input

There will be at most 20 test cases. Ease case starts with a line containing two integers N and M. where N is the length of the contact list and M is the number of groups. N lines then follow. Each line contains a friend‘s name and the groups the friend could belong to. You can assume N is no more than 1000 and M is no more than 500. The names will contain alphabet letters only and will be no longer than 15 characters. No two friends have the same name. The group label is an integer between 0 and M - 1. After the last test case, there is a single line `0 0‘ that terminates the input.

Output

For each test case, output a line containing a single integer, the size of the largest contact group.

Sample Input

3 2

John 0 1

Rose 1

Mary 1
5 4

ACM 1 2 3

ICPC 0 1

Asian 0 2 3

Regional 1 2

ShangHai 0 2

0 0

Sample Output

2

2

解析:有n个人,m个分组,每个人都可以分到指定的几个组合,问怎么分组使得m个组中的最大组的大小最小。

显然是一对多的关系,然后我们二分 二分图多重匹配 的限制,找到可以使n个人都可以匹配的最小限制就好了。

AC代码

#include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define all(a) (a).begin(), (a).end()
#define fillchar(a, x) memset(a, x, sizeof(a))
#define huan printf("\n")
#define debug(a,b) cout<<a<<" "<<b<<" "<<endl
#define ffread(a) fastIO::read(a)
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int MAXN = 1000+10;
const int MAXM = 500+10;
int uN,vN;
int g[MAXN][MAXM];
int linker[MAXM][MAXN];
bool used[MAXM];
int num[MAXM],limit;
bool dfs(int u)
{
    for(int v = 0; v < vN; v++)
        if(g[u][v] && !used[v])
        {
            used[v] = true;
            if(linker[v][0] < limit)
            {
                linker[v][++linker[v][0]] = u;
                return true;
            }
            for(int i = 1; i <= linker[v][0]; i++)
                if(dfs(linker[v][i]))
                {
                    linker[v][i] = u;
                    return true;
                }
        }
    return false;
}
int hungary()
{
    int res = 0,flag=0;
    for(int i = 0; i < vN; i++)
        linker[i][0] = 0;
    for(int u = 0; u < uN; u++)
    {
        memset(used,false,sizeof(used));
        if(dfs(u))
            res++;
        else
        {
            flag=1;
            break;
        }
    }
    return flag;
}
int main()
{
    while(scanf("%d%d",&uN,&vN)!=EOF&&uN&&vN)
    {
        fillchar(g,0);
        getchar();
        for(int i=0;i<uN;i++)
        {
            char s[2000];
            gets(s);
            int len=strlen(s);
            int num=0,jishu=0;
            for(int j=len-1;j>=0;j--)
            {
                if(s[j]==‘ ‘)
                {
                    g[i][num]=1;
                    num=jishu=0;
                }
                else if(s[j]>=‘0‘&&s[j]<=‘9‘)
                {
                    num+=(int)(s[j]-‘0‘)*pow(10,jishu);
                    jishu++;
                }
                else
                    break;
            }
        }
        int l=0,r=uN;
        while(l<=r)
        {
            limit=(l+r)/2;
            //cout<<limit<<endl;
            if(!hungary())
                r=limit-1;
            else
                l=limit+1;
        }
        printf("%d\n",r+1);
    }
}

原文地址:https://www.cnblogs.com/stranger-/p/9822440.html

时间: 2024-11-07 04:39:43

HDU 1669 二分图多重匹配+二分的相关文章

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【二分图多重匹配+二分答案】

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

Optimal Milking(二分图多重匹配+二分)(网络流)

Optimal Milking Time Limit:2000MS     Memory Limit:30000KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 2112 Description FJ has moved his K (1 <= K <= 30) milking machines out into the cow pastures among the C (1 <= C <= 20

POJ2112:Optimal Milking(Floyd+二分图多重匹配+二分)

Optimal Milking Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 20262   Accepted: 7230 Case Time Limit: 1000MS Description: FJ has moved his K (1 <= K <= 30) milking machines out into the cow pastures among the C (1 <= C <= 200) c

Steady Cow Assignment(二分图多重匹配+二分)(网络流)

Steady Cow Assignment Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 3189 Description Farmer John's N (1 <= N <= 1000) cows each reside in one of B (1 <= B <= 20) barns which, of cou

hdu 3605(二分图多重匹配,匈牙利算法)

题意:有n个人可以逃到m个星球取,下面每一行有m个数,是第i个人是否可以逃到第j个星球.最后一行是m个星球最大可以生存的人数. 问是否可以全部逃离. 思路:之前二分图最大匹配是一个点最多匹配一个的,而这里每个星球可以匹配多个人. 但思路是一样的,每个人去匹配星球,如果可以匹配   并且人数小于该星球可以容纳人数就匹配,可以匹配但人数超过了,就要考虑该星球的人是否可以让位置到其他星球去,  比最大匹配多了一个for循环考虑多个人而已. #include<iostream> #include<

kuangbin带你飞 匹配问题 二分匹配 + 二分图多重匹配 + 二分图最大权匹配 + 一般图匹配带花树

二分匹配:二分图的一些性质 二分图又称作二部图,是图论中的一种特殊模型. 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图. 1.一个二分图中的最大匹配数等于这个图中的最小点覆盖数 König定理是一个二分图中很重要的定理,它的意思是,一个二分图中的最大匹配数等于这个图中的最小点覆盖数.如果你还不知道什么是最小点覆盖,我也在这里说一下:假如选

HDU 3605 Escape【二分图多重匹配】

题意: 有n个人去m个星球  告诉你每个人想去哪些星球和每个星球最多容纳多少人,问能不能让所有人都满足 分析: 二分图多重匹配 代码: 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <vector> 5 using namespace std; 6 7 const int maxn = 100005; 8 const int maxm = 15; 9 10

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

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