题意:
给了一个N*N的图...#代表可能的油田..而油田是由1*2 or 2*1的长方形构成的...问最多有多少个的确是油田...
题解:
把点分成奇偶的(不分也行..结果除以二)...然后跑匈牙利就是..但是..直接搞会超时..可能#是比较少的把..离散化出来效率瞬间就叼炸天了.....
Program:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<time.h>
#include<map>
#include<algorithm>
#define ll long long
#define eps 1e-5
#define oo 1<<30
#define pi acos(-1.0)
#define MAXN 360000
#define MAXM 360000
using namespace std;
struct node
{
int y,next;
}line[MAXM];
int Lnum,_next[MAXN],match[MAXN];
bool used[MAXN];
char s[605][605];
void addline(int x,int y)
{
line[++Lnum].next=_next[x],_next[x]=Lnum,line[Lnum].y=y;
}
bool dfs(int x)
{
for (int k=_next[x];k;k=line[k].next)
{
int y=line[k].y;
if (used[y]) continue;
used[y]=true;
if (!match[y] || dfs(match[y]))
{
match[y]=x;
return true;
}
}
return false;
}
int getmax(int n)
{
int sum=0;
memset(match,0,sizeof(match));
for (int i=1;i<=n;i++)
{
memset(used,false,sizeof(used));
sum+=dfs(i);
}
return sum;
}
int main()
{
int cases,n,T,i,j,num;
scanf("%d",&T);
for (cases=1;cases<=T;cases++)
{
scanf("%d",&n);
for (i=0;i<n;i++) scanf("%s",s[i]);
Lnum=0,memset(_next,0,sizeof(_next));
num=0;
for (i=0;i<n;i++)
for (j=0;j<n;j++)
if (s[i][j]=='#' && (i+j)%2==0)
{
num++;
if (i && s[i-1][j]=='#') addline(num,(i-1)*n+j);
if (j && s[i][j-1]=='#') addline(num,i*n+j-1);
if (i!=n-1 && s[i+1][j]=='#') addline(num,(i+1)*n+j);
if (j!=n-1 && s[i][j+1]=='#') addline(num,i*n+j+1);
}
printf("Case %d: %d\n",cases,getmax(num));
}
return 0;
}