hdu 1498 50 years, 50 colors(最小覆盖点数)

题意:
 给你一个n*n的矩阵,在矩阵中分布着s种颜色的气球,给你k次扎破气球
 的操作,每次操作可以扎破一行,或一列的同一颜色的气球。问在k次操
 作后有那几种颜色的气球是不能被完全扎破的.
解题:
  利用二分图匹配,寻找每一种颜色对应的最大匹配(行和列分别为X集合,Y集合;map[i,j]代表一个搭配),

  如果大于k则输出"-1",否则输出颜色的递增序列

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <list>
#include <queue>
#include <map>
#include <stack>
using namespace std;
#define L(i) i<<1
#define R(i) i<<1|1
#define INF  0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-3
#define maxn 100010
#define MOD 1000000007

int n,m,match[110];
int mp[110][110],vis[110];
int Find(int u,int c)
{
    for(int v = 0; v < n; v++)
        if(mp[u][v] == c && !vis[v])
        {
            vis[v] = 1;
            if(match[v] == -1 || Find(match[v],c))
            {
                match[v] = u;
                return 1;
            }
        }
    return 0;
}
int main()
{
    int t,C = 1;
    while(scanf("%d%d",&n,&m) && (n+m))
    {
        memset(mp,0,sizeof(mp));
        for(int i = 0; i < n; i++)
            for(int j = 0; j < n; j++)
                scanf("%d",&mp[i][j]);
        int ans[110],t = 0;
        for(int i = 1; i <= 50; i++)
        {
            int cnt = 0;
            memset(match,-1,sizeof(match));
            for(int j = 0; j < n; j++)
            {
                memset(vis,0,sizeof(vis));
                cnt += Find(j,i);
            }
            if(cnt > m)
                ans[t++] = i;
        }
        if(!t)
            printf("-1");
        else
            for(int i = 0; i < t; i++)
                printf(i == 0?"%d":" %d",ans[i]);
        printf("\n");
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值