Oil Skimming【最大匹配】

版权声明:https://blog.csdn.net/qq_41730082 https://blog.csdn.net/qq_41730082/article/details/86726855

Thanks to a certain "green" resources company, there is a new profitable industry of oil skimming. There are large slicks of crude oil floating in the Gulf of Mexico just waiting to be scooped up by enterprising oil barons. One such oil baron has a special plane that can skim the surface of the water collecting oil on the water's surface. However, each scoop covers a 10m by 20m rectangle (going either east/west or north/south). It also requires that the rectangle be completely covered in oil, otherwise the product is contaminated by pure ocean water and thus unprofitable! Given a map of an oil slick, the oil baron would like you to compute the maximum number of scoops that may be extracted. The map is an NxN grid where each cell represents a 10m square of water, and each cell is marked as either being covered in oil or pure water.

Input

The input starts with an integer K (1 <= K <= 100) indicating the number of cases. Each case starts with an integer N (1 <= N <= 600) indicating the size of the square grid. Each of the following N lines contains N characters that represent the cells of a row in the grid. A character of '#' represents an oily cell, and a character of '.' represents a pure water cell.

Output

For each case, one line should be produced, formatted exactly as follows: "Case X: M" where X is the case number (starting from 1) and M is the maximum number of scoops of oil that may be extracted.

Sample Input

1
6
......
.##...
.##...
....#.
....##
......

Sample Output

Case 1: 3

  刚写的时候,算了下时间复杂度,最坏就是600*600*100应该会T,但是想不到其他什么办法了,写吧,然后交吧,然后!我的天A了!!!还在等着T,没想到那么快就A了!!!

  思路就是附近匹配,既然需要1*2的这样的格子,那么就是告诉我们要两个连续的格子就是了,并且还不能重复利用,所以如果一个匹配上了,就可以看作是两个都匹配了,就把两个的关系叠加上去。


#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
#define MP(a, b) make_pair(a, b)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN = 605;
int N, cnt, head[maxN], num, re[maxN][maxN], link[maxN*maxN];
char mp[maxN][maxN];
struct node
{
    int x, y;
    node(int a=0, int b=0):x(a), y(b) {}
}a[maxN*maxN];
struct Eddge
{
    int nex, to;
    Eddge(int a=-1, int b=0):nex(a), to(b) {}
}edge[maxN*maxN];
void addEddge(int u, int v)
{
    edge[cnt] = Eddge(head[u], v);
    head[u] = cnt++;
}
bool vis[maxN*maxN];
bool match(int u)
{
    for(int i=head[u]; i!=-1; i=edge[i].nex)
    {
        int v = edge[i].to;
        if(vis[v]) continue;
        vis[v] = true;
        if(!link[v] || match(link[v]))
        {
            link[v] = u;
            link[u] = v;
            return true;
        }
    }
    return false;
}
int Hungery()
{
    int ans = 0;
    for(int i=1; i<=num; i++)
    {
        memset(vis, false, sizeof(vis));
        if(!link[i] && match(i)) ans++;
    }
    return ans;
}
inline void init()
{
    cnt = num = 0;
    memset(head, -1, sizeof(head));
}
int main()
{
    int T;  scanf("%d", &T);
    memset(mp, 0, sizeof(mp));
    for(int Cas=1; Cas<=T; Cas++)
    {
        init();
        scanf("%d", &N);
        for(int i=1; i<=N; i++) scanf("%s", mp[i] + 1);
        for(int i=1; i<=N; i++)
        {
            for(int j=1; j<=N; j++)
            {
                if(mp[i][j] == '#')
                {
                    a[++num] = node(i, j);
                    re[i][j] = num;
                    link[num] = 0;  //初始化开始的值链接关系
                    if(mp[i-1][j] == '#') { addEddge(re[i-1][j], num); addEddge(num, re[i-1][j]); }
                    if(mp[i][j-1] == '#') { addEddge(re[i][j-1], num); addEddge(num, re[i][j-1]); }
                }
            }
        }
        printf("Case %d: %d\n", Cas, Hungery());
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41730082/article/details/86726855