Description
Analysis
二分图匹配。
由于本人之前中了网络流的毒,此题便乱搞搞出来了。
首先,对于网络流的知识,可以参考专题“网络流与线性规划”
这题,就是最大点独立集。
但是不是裸的,因为有”#”影响一行情况。
所以,一行或一列中,被”#”隔开的部分视为不同的行或列。
Code
#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int N=53,M=5105;
int n,m,st,x[N][N],y[N][N];
int pos[M],bz[M],a[M][M];
bool p[M];
char map[N][N];
void link(int u,int v)
{
a[u][++a[u][0]]=v;
}
bool match(int v)
{
if(bz[v]==st) return 0;
bz[v]=st;
fo(i,1,a[v][0])
{
int u=a[v][i];
if(!pos[u] || match(pos[u]))
{
pos[u]=v;
return 1;
}
}
return 0;
}
int main()
{
scanf("%d %d\n",&n,&m);
fo(i,1,n)
{
fo(j,1,m) scanf("%c",&map[i][j]);
scanf("\n");
}
int xx=0,yy=0;
fo(i,1,n)
{
xx++;
fo(j,1,m)
{
if(map[i][j]=='#') xx++;
if(map[i][j]=='*') x[i][j]=xx;
}
}
fo(j,1,m)
{
yy++;
fo(i,1,n)
{
if(map[i][j]=='#') yy++;
if(map[i][j]=='*') y[i][j]=yy;
}
}
int mx=0;
fo(i,1,n)
fo(j,1,m)
if(map[i][j]=='*')
{
link(x[i][j],xx+y[i][j]);
p[x[i][j]]=p[xx+y[i][j]]=1;
mx=max(mx,xx+y[i][j]);
}
int tot=0,t=0;
fo(i,1,mx)
if(p[i]) tot++;
for(st=1;st<=mx;st++)
if(match(st)) t++;
printf("%d",t);
return 0;
}