uva12549 Sentry Robots(二分图)

HDU 5093 是一样的

题意:

在一个Y行X列的网格里有空地(.),重要位置(*)和障碍物(#),用最少的机器人看守所有重要位置,每个机器人要放在一个格子里,面朝上下左右4个方向之一。机器人会发出激光,一直射到障碍物为止,沿途都是看守范围。

思路:给行块和列块标号,在重要位置处连边,然后匹配

#include <stdio.h>
#include <string.h>

int str[105][105];
int match[2550],x[105][105],y[105][105];
bool mp[2500][2500],used[2550];
int cntx,cnty;

bool dfs(int u)
{
    for(int i = 0; i < cnty; i++) {
        if(mp[u][i] && !used[i]) {
            used[i] = 1;
            if(match[i] == -1 || dfs(match[i])) {
                match[i] = u;
                return true;
            }
        }
    }
    return false;
}
int max_match()
{
    int ans = 0;
    memset(match,-1,sizeof(match));
    for(int i = 0; i < cntx; i++) {
        memset(used,0,sizeof(used));
        if(dfs(i)){
            ans++;
        }
    }
    return ans;
}

int main(void)
{
    int T;
    scanf("%d",&T);
    while(T--) {
        int n,m;
        scanf("%d%d",&n,&m);
        memset(x,0,sizeof(x));
        memset(y,0,sizeof(y));
        memset(mp,0,sizeof(mp));
        memset(str,0,sizeof(str));
        int p,xx,yy;
        scanf("%d",&p);
        while(p--) {
            scanf("%d %d",&xx,&yy);
            xx--;yy--;
            str[xx][yy] = 1;
        }
        scanf("%d",&p);
        while(p--) {
            scanf("%d %d",&xx,&yy);
            xx--;yy--;
            str[xx][yy] = 2;
        }

        cntx = -1;
        for(int i = 0; i < n; i++) {
            bool flag = true;
            for(int j = 0; j < m; j++) {
                if(str[i][j] == 1) {
                    if(flag) ++cntx;
                    x[i][j] = cntx;
                    flag = false;
                }
                if(str[i][j] == 2) {
                    flag = true;
                }
            }
        }
        //给列块标号
        cnty = -1;
        for(int i = 0; i < m; i++) {
            bool flag = true;
            for(int j = 0; j < n; j++) {
                if(str[j][i] == 1) {
                    if(flag) ++cnty;
                    y[j][i] = cnty;
                    flag = false;
                }
                if(str[j][i] == 2) {
                    flag = true;
                }
            }
        }
        cntx++;
        cnty++;
        //建图
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < m; j++) {
                if(str[i][j] == 1) {
                    mp[x[i][j]][y[i][j]] = 1;
                }
            }
        }
        printf("%d\n",max_match());
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/GYH0730/article/details/81504916
今日推荐