hdu 3605 二分图多重匹配

转载地址:http://www.cnblogs.com/Griselda/archive/2012/09/17/2689345.html
题意:

给出每个人适合住的星球信息和该星球能住多少人 

第一行给出n m 代表有 n 个人 m 个星球

然后接下来n行每行m个数字 1代表适合第 i 个星球 0 代表不适合第 i 个星球

最后一行m个数表示第 i 个星球最多可以住多少个人

问是不是所有人都可以住到星球上

思路:

多重匹配

Tips:

多重匹配即 X 集合上的点对应 Y 集合上多个点 而 Y 集合上的点对应 X 中的一个点
#include <stdio.h>//感觉类似于二分匹配
#include <cstring>
#define clr(x) memset(x, 0, sizeof(x))
const int INF = 0x1f1f1f1f;

bool G[100010][15];//关系矩阵
int limit[15];//限制条件
bool vis[15];
int v1, v2;
int v[15];//记录当前星球的数目
int vv[15][100010];//模拟容器

bool find(int u)//找u的匹配星球
{
    int i, j, k;
    for(i = 0; i < v2; ++i) {
        if(G[u][i] && !vis[i]) {
            vis[i] = true;
            if(v[i] < limit[i]) {//如果还有容量就加入进去
                vv[i][v[i]++] = u;
                return true;
            }

            for(j = 0; j < v[i]; ++j) {//没有容量了,就将原来容量里面的的找是否可以匹配
                if(find(vv[i][j])) {
                    vv[i][j] = u;//如果可以匹配就将当前容量里面的替换为u
                    return true;
                }
            }
        }
    }
    return false;
}

bool solve()
{
    clr(v), clr(vv);
    for(int i = 0; i < v1; ++i) {//和二分匹配思想差不多
        clr(vis);
        if(!find(i)) {//如果没有匹配的说明不能完全匹配
            return false;
        }
    }
    return true;
}

int main()
{
    int i, j, k;
    while(scanf("%d %d", &v1, &v2) != EOF)
    {
        clr(G);

        for(i = 0; i < v1; ++i)
        for(j = 0; j < v2; ++j) {
            scanf("%d", &G[i][j]);
        }
        for(i = 0; i < v2; ++i)
            scanf("%d", &limit[i]);

        if(solve()) puts("YES");
        else puts("NO");
    }

    return 0;
}

posted @ 2014-07-26 11:21  HYDhyd  阅读(102)  评论(0编辑  收藏  举报