棋盘游戏

这里写图片描述

Sample Input
3 3 4
1 2
1 3
2 1
2 2
3 3 4
1 2
1 3
2 1
3 2

Sample Output
Board 1 have 0 important blanks for 2 chessmen.
Board 2 have 3 important blanks for 3 chessmen.

//题意:同行、同列中只能有一个棋子,给定一个地图,求该地图中能放的最大棋子数和重要点个数(介绍见思路)。

//思路:匈牙利算法模板题。直接套模板可求最大棋子数。把一个原本可以放棋子的地方(map[][]==1的点)设置成不能放棋子(map[][]==0),若最大棋子数变少了,那么该点为“重要点”。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <cstdlib>
#include <algorithm>
using namespace std;

#define MAX 100+10

int n, m, k;
int x[MAX*MAX], y[MAX*MAX];  //存放可以放棋子的点的坐标
int map[MAX][MAX]; //地图
int used[MAX], visit[MAX];

int find(int x)
{
    int i;
    for (i = 1; i <= m; i++)
    {
        if (map[x][i] == 1 && visit[i] == 0)
        {
            visit[i] = 1;
            if (used[i] == 0 || find(used[i]) == 1)
            {
                used[i] = x;
                return 1;
            }
        }
    }
    return 0;
}

//匈牙利算法(递归实现)
int hungarian()
{
    int i, sum = 0;
    memset(used, 0, sizeof(used));
    for (i = 1; i <= n; i++)
    {
        memset(visit, 0, sizeof(visit));
        if (find(i))
            sum++;
    }
    return sum;
}

int main()
{
    int i, tt = 1;
    while (~scanf("%d%d%d", &n, &m, &k))
    {
        memset(map, 0, sizeof(map));
        for (i = 1; i <= k; i++)
        {
            scanf("%d%d", &x[i], &y[i]);
            map[x[i]][y[i]] = 1;
        }

        int ans = hungarian(); //求棋子的最大个数
        int sum = 0;

        //若把一个原本是1的地方换成0后,最大棋子个数减小,则该点为重要点
        for (i = 1; i <= k; i++)
        {
            map[x[i]][y[i]] = 0;
            int num = hungarian();
            if (num < ans)
                sum++;
            map[x[i]][y[i]] = 1;
        }

        printf("Board %d have %d important blanks for %d chessmen.\n", tt, sum, ans);
        tt++;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值