poj2226/bzoj1735 Muddy Fields 最小点覆盖
建图有些麻烦,把每个最长的1*x作为一个点,建图,跑dinic即可
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
using namespace std;
char s[55][55];
int n,m,p1=0,p2=0,S,T,lin[8000],level[8000],ans=0,bel[55][55],len=0,q[8000];
struct one
{
int y,next,v,reverse;
};
one e[100000];
void insert(int xx,int yy)
{
e[++len].next=lin[xx];
lin[xx]=len;
e[len].y=yy;
e[len].v=1;
e[len].reverse=len+1;
e[++len].next=lin[yy];
lin[yy]=len;
e[len].y=xx;
e[len].v=0;
e[len].reverse=len-1;
}
bool makelevel()
{
memset(level,-1,sizeof(level));
q[1]=0;
level[0]=0;
int head=1,tail=1;
for(int head=1;head<=tail;head++)
{
for(int i=lin[q[head]];i;i=e[i].next)
{
if(level[e[i].y]<0&&e[i].v>0)
{
level[e[i].y]=level[q[head]]+1;
q[++tail]=e[i].y;
}
}
}
return level[T]>=0;
}
int MAXflow(int aa,int flow)
{
if(aa==T)return flow;
int maxflow=0,d=0;
for(int i=lin[aa];i&&maxflow<flow;i=e[i].next)
{
if(e[i].v&&level[e[i].y]==level[aa]+1)
{
if(d=MAXflow(e[i].y,min(flow-maxflow,e[i].v)))
{
e[i].v-=d;
e[e[i].reverse].v+=d;
maxflow+=d;
}
}
}
if(maxflow<=0) level[aa]=-1;
return maxflow;
}
void dinic()
{
int d;
while(makelevel())
while(d=MAXflow(0,99999999))
ans+=d;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
memset(lin,0,sizeof(lin));
memset(level,0,sizeof(level));
memset(bel,0,sizeof(bel));
p1=0;p2=0;
len=0;
ans=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>s[i][j];
for(int i=1;i<=n;i++)
{
int j=1;
while(j<=m)
{
if(s[i][j]=='*')
{
p1++;
bel[i][j]=p1;
while(j<=m&&s[i][j+1]=='*')
{
j++;
bel[i][j]=p1;
}
}
j++;
}
}
p2=p1;
for(int j=1;j<=m;j++)
{
int i=1;
while(i<=n)
{
if(s[i][j]=='*')
{
p2++;
insert(bel[i][j],p2);
while(i<=n&&s[i+1][j]=='*')
{
i++;
insert(bel[i][j],p2);
}
}
i++;
}
}
S=0;T=p1+p2+1;
for(int i=1;i<=p1;i++)insert(S,i);
for(int i=1;i<=p2;i++)insert(i+p1,T);
dinic();
printf("%d\n",ans);
}
return 0;
}

浙公网安备 33010602011771号