码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 1045 最大匹配

时间:2020-08-24 16:59:26      阅读:76      评论:0      收藏:0      [点我收藏+]

标签:建图   scan   strong   题意   cst   ems   stdin   open   stack   

xg

题意

  给了一个4*4矩阵。图中有的点代表山。要求在这个矩阵上放碉堡,碉堡可以上下,左右攻击所能看到的碉堡,山可以阻挡两边碉堡互相看到,且碉堡不能放到山上。问最多可以放多少个碉堡。

思路

  数据范围小可以暴力。

  但是用最大匹配解:

  在矩阵上的最大匹配问题,可以转化为x,y坐标的最大匹配。

  因为碉堡能进行格挡,则可以把x,y行问题转化为一块一块。

  技术图片

 

  上图是x坐标的块,然后和y的块建图最大匹配即可。

#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <iomanip>
#include <algorithm>
#include <queue>
#include <stack>
#include <set>
#include <vector> 

#define bug cout<<"--------------"<<endl
#define sp ‘ ‘
using namespace std;
typedef long long ll;

const int maxn = 100;
int n;
int a[maxn][maxn];
int tot = 0;
int head[maxn],ver[maxn],edge[maxn],nextt[maxn];
void add(int x,int y)
{
    ver[++tot] = y,nextt[tot] = head[x] , head[x] = tot;
}
int match[maxn],vis[maxn];
bool dfs(int x)
{
    for(int i = head[x],y;i; i = nextt[i]){    
        if(!vis[y = ver[i]]){
            vis[y] = 1;
            if(!match[y] || dfs(match[y])){
                match[y] = x; return 1;
            }
        }
    }
    return 0;
}
int main()
{
    //freopen("input.txt", "r", stdin);
    while(scanf("%d",&n) != EOF){
        if(n == 0) break;
        int cnt = 0;
        memset(a,0,sizeof(a));
        memset(head,0,sizeof(head));
        memset(match,0,sizeof(match));
        tot = 0;
        for(int i = 1; i<=n;++i){
            for(int j=1;j<=n;++j){
                char c;
                cin>>c;
                if(c == .) a[i][j] = 1;
            }
        }
        for(int i = 1;i<=n;++i){
            for(int j = 1;j <=n;++j){
                if(a[i][j]){
                    if(a[i][j-1] == 0) cnt++;
                    a[i][j] = cnt;
                }
            }
        }
        int nub = cnt;
        for(int j = 1;j <=n;++j){
            for(int i = 1;i<=n;++i){
                if(a[i][j]){
                    if(a[i-1][j] == 0) cnt++;
                    add(a[i][j],cnt);
                    //add(cnt,a[i][j]);
                }
            }
        }
        int ans = 0;
        for(int i = 1;i <= nub;++i){
            memset(vis,0,sizeof(vis));
            if(dfs(i)) ans++;
        } 
        printf("%d\n",ans );
        //bug;

    }
}

 

HDU 1045 最大匹配

标签:建图   scan   strong   题意   cst   ems   stdin   open   stack   

原文地址:https://www.cnblogs.com/jrfr/p/13552328.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!