HDU 1498

HDU 1498 50 years,50 colors

题意

n*n的矩形中放入颜色值为[1,50]的气球,要求每一个人扎k次,每扎一次,可将同行或者同列相同颜色的气球全部扎破。求是否存在不可能全部扎破的气球,按照升序规律输出气球的颜色。

思路

每种颜色进行最小点覆盖运算,如果最小覆盖点num>k,则该颜色气球不能全部扎破。
矩形行列分别为集合A和集合B,如果判断颜色k气球,则如果map [i] [j] = k,则表示存在一条边,这样便可以转换成最小点覆盖问题,只需要找出最小的点,清除掉两集合之间所有的边即。

代码

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>

using namespace std;

const int N = 105;
int map[N][N]; //气球的总图
int link[N]; //link[j]:第j列被扎过时,扎的气球位置的行(无则-1)
int useif[N]; //第i列是否被扎过
int ans[N]; //记录不能全部扎破的气球,ans[i]为某颜色数值
int len;
int n, k;

int dfs(int t, int col)
{
    for(int i = 0; i < n; i++)
    {
        if(!useif[i] && map[t][i] == col)
        {
            useif[i] = 1;
            //寻找增广路,如果有增广路,说明该位置需要扎气球
            if(link[i] == -1 || dfs(link[i], col))
            {
                link[i] = t;//说明i列被扎过,初始扎的气球位置在t行
                return 1;
            }
        }
    }
    return 0;
}

int maxMatch(int col)
{
    memset(link, -1, sizeof(link));
    int num = 0;
    for(int i = 0; i < n; i++)
    {
        memset(useif, 0, sizeof(useif));//对每一行都要初始化
        if(dfs(i, col)) num ++;
    }
    return num;
}

int main()
{
    while(scanf("%d %d", &n, &k) && n && k )
    {
        memset(map, 0, sizeof(map));
        len = 0;
        for(int i = 0; i < n; i++)
            for(int j=0;j<n;j++)
                scanf("%d", &map[i][j]);
        for(int i = 1; i <= 50; i++)
        {
            if(maxMatch(i) > k)//每种颜色都判断一次,执行n次最小点覆盖
                ans[len ++] = i;
        }
        if(!len)
            printf("-1\n");
        else
        {
            for(int i=0;i<len-1;i++)
                printf("%d ", ans[i]);
            printf("%d\n",ans[len - 1]);
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值