A

题意:一个阵地可以向四周扫射,求出来最多能修多少个阵地,墙不可以被扫射透,阵地不能同行或者或者列(有墙隔着例外)
分析:很久以前就做过这道题。。当时是练习深搜来着,不过时间复杂度比较高,现在再看突然发现原来可以用二分图匹配来做,时间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 ", ans);
    }

    return 0;

} 

原文地址:https://www.cnblogs.com/liuxin13/p/4694264.html