zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    Network (poj1144)
    C. Hongcow Builds A Nation
    ZYB loves Xor I(hud5269)
    D. Chloe and pleasant prizes
    Game(hdu5218)
    约瑟夫环的递推方法
    Misaki's Kiss again(hdu5175)
    Exploration(hdu5222)
    B. Arpa's weak amphitheater and Mehrdad's valuable Hoses
    C. Arpa's loud Owf and Mehrdad's evil plan
  • 原文地址:https://www.cnblogs.com/chenchengxun/p/4718609.html
Copyright © 2011-2022 走看看