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

题意:N个人,M个团体。每个人有属于自己的一些团体编号。将每个人分配到自己属于的团体中,问这个人数最多的团体其人数最小值是多少。

分析:一个一对多的二分图匹配,且是最大值最小化问题。二分图的多重匹配建立在匈牙利算法的基础上,令每个Y部的点可匹配多个点,但是规定其上限,超过上限就要在已有的匹配点中寻找增广路。对于X部的点,只要有一个点没有被匹配,那么算法失败。以此二分确定答案,注意二分的姿势...

该题可做模板。

#include<iostream>
#include<stdio.h>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long LL;
const int maxn = 1e3+5,maxm = 5e5+5;
int N,M;
struct Node{
    int K[maxn];
}link[maxn];
int cnt[maxn];
struct Edge{
    int to,next;
}edges[maxm];
int head[maxn],tot;
int linker[maxn];
bool used[maxn];

void init()
{
    tot=0;
    memset(head,-1,sizeof(head));
}

void AddEdge(int u,int v)
{
    edges[tot].to = v;
    edges[tot].next = head[u];
    head[u] = tot++;
}

bool dfs(int u,int limit){
    int v;
    for(int i=head[u];~i;i = edges[i].next){
        v = edges[i].to;
        if(!used[v]){
            used[v]=true;
            if(cnt[v]<limit){
                link[v].K[cnt[v]++]=u;
                return true;
            }
            for(int j=0;j<cnt[v];++j){
                if(dfs(link[v].K[j],limit)){
                    link[v].K[j]=u;
                    return true;
                }
            }
        }
    }
    return false;
}

bool hungary(int limit){
    memset(cnt,0,sizeof(cnt));
    for(int u=1;u<=N;u++){
        memset(used,0,sizeof(used));
        if(!dfs(u,limit)) return false;     //只要有一个人不能匹配则失败
    }
    return true;
}

int main()
{
    #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    #endif
    int T,u,v,tmp,k;
    char c;
    while(scanf("%d%d",&N,&M)==2){
        if(!N) break;
        init();
        for(int u=1;u<=N;++u){
            char op[maxn];
            scanf("%s",op);
            while(true){
                scanf("%d%c",&v,&c);
                AddEdge(u,v+1);
                if(c == ‘\n‘) break;
            }
        }
        int L=1,R=N,mid,ans=N;
        while(L<=R){
            mid = (L+R)>>1;
            if(hungary(mid)){
                ans = mid;
                R = mid-1;
            }
            else L=mid+1;
        }
        printf("%d\n",ans);
    }
    return 0;
}

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

原文地址:https://www.cnblogs.com/xiuwenli/p/9374550.html

时间: 2024-08-05 08:40:09

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(多重匹配+二分)

题意: Jamie有很多联系人,但是很不方便管理,他想把这些联系人分成组,已知这些联系人可以被分到哪个组中去,而且要求每个组的联系人上限最小,即有一整数k,使每个组的联系人数都不大于k,问这个k最小是多少? 题目分析: 多重匹配,二分枚举所有极限值. 多重匹配如何匹配? 假如我们有两个集合X, Y 但是呢 Y可以匹配多个X, 这个时候我们需要给这个匹配设置一个极限值.比如Y可以匹配三个X. 假如匹配的值不到三个X我们就将他们匹配, 直到到达极限值为止.在这里Y要保存所有的与之匹配的X,若是匹配值

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

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个组,现在给出你每个人可以去的组的编号,求分成的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

Jamie&#39;s Contact Groups---hdu1669--poj2289(多重匹配)

题目链接 题意:Jamie有很多联系人,但是很不方便管理,他想把这些联系人分成组,已知这些联系人可以被分到哪个组中去,而且要求每个组的联系人上限最小,即有一整数k,使每个组的联系人数都不大于k,问这个k最小是多 少? 一对多的二分图的多重匹配.二分图的多重匹配算法的实现类似于匈牙利算法,对于集合x中的元素xi,找到一个与其相连的元素yi后,检查匈牙利算法的两个条件是否成立,若yi未被匹配,则将 xi,yi匹配.否则,如果与yi匹配的元素已经达到上限,那么在所有与yi匹配的元素中选择一个元素,检查

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

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