A - Fire Net - hdu 1045(二分图匹配)

题意:一个阵地可以向四周扫射,求出来最多能修多少个阵地,墙不可以被扫射透,阵地不能同行或者或者列(有墙隔着例外)
分析:很久以前就做过这道题。。当时是练习深搜来着,不过时间复杂度比较高,现在再看突然发现原来可以用二分图匹配来做,时间soso的
******************************************************************
#include<stdio.h>
#include< string.h>
#include<algorithm>
using  namespace std;

const  int MAXN =  105;
const  int oo = 1e9;

bool G[MAXN][MAXN], used[MAXN];
int p[MAXN], x, y;
struct node{ int x, y;}a[MAXN][MAXN];

bool Find( int u)
{ /// 匈牙利算法匹配
     for( int i= 1; i<=y; i++)
    {
         if(G[u][i] && used[i] ==  false)
        {
            used[i] =  true;
             if(!p[i] || Find(p[i]))
            {
                p[i] = u;
                 return  true;
            }
        }
    }

     return  false;
}

int main()
{
     int N;

     while(scanf( " %d ", &N), N)
    {
         int i, j;
         char s[MAXN][MAXN];

         for(i= 0; i<N; i++)
            scanf( " %s ", s[i]);

        x = y =  0;

         for(i= 0; i<N; i++)
         for(j= 0; j<N; j++)
        { /// 把图分割,以相连的‘.’为行和列重新分配编号
             if(s[i][j] ==  ' . ')
            {
                 if(j ==  0 || s[i][j- 1] ==  ' X ')
                    x++;
                a[i][j].x = x;
            }
             if(s[j][i] ==  ' . ')
            {
                 if(j ==  0 || s[j- 1][i] ==  ' X ')
                    y++;
                a[j][i].y = y;
            }
        }

        memset(G,  0sizeof(G));

         for(i= 0; i<N; i++)
         for(j= 0; j<N; j++)
        {
             if(s[i][j] ==  ' . ')
            {
                 int u = a[i][j].x;
                 int v = a[i][j].y;
                G[u][v] =  true; /// 用行匹配列
            }
        }

         int ans =  0;
        memset(p,  0sizeof(p));
         for(i= 1; i<=x; i++)
        {
            memset(used,  falsesizeof(used));
             if( Find(i) ==  true )
                ans++;
        }

        printf( " %d\n ", ans);
    }

     return  0;

} 

转载于:https://www.cnblogs.com/liuxin13/p/4694264.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值