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;
}

  

posted @ 2018-05-16 16:26  mybing  阅读(148)  评论(0编辑  收藏  举报