poj 2226 Muddy Fields

来源:互联网 发布:手机淘宝退款率怎么看 编辑:程序博客网 时间:2024/04/29 11:30

//POJ2226 最小点覆盖=最大二分匹配
//难在构图,其实边数就是星的个数
//要求覆盖所有的星的最少板数就是求最小点覆盖
#include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
using namespace std;

char grid[60][60];
int bigraph[2000][2000];
int mark[2000];
int link[2000];
int hash[60][60];
int n,m;
int l,r;
int can(int v)
{
 for (int j=0;j<r;j++)
  if (!mark[j] && bigraph[v][j])
  {
           mark[j]=1;
     if (link[j]==-1 || can(link[j]))
     {
      link[j]=v;
      return 1;
     }
  }
 return 0;
}

int main()
{

 scanf("%d%d",&n,&m);
 for (int i=0;i<n;i++)
  scanf("%s",grid[i]);
    l=r=0;
 
    //数出连续行的数目,即X部点数,并用hash[i][j]标记该点属于X部的哪个点(一个行星)
 for (int i=0;i<n;i++)
  for (int j=0;j<m;j++)
   if (grid[i][j]=='*')
   {
    if (!j || grid[i][j-1]=='.')
     l++;
    hash[i][j]=l-1;
   }
 
 //数出连续行的数目,即Y部点数,并连线,连线方法是:
    //星行和星列有交点则连一条边,最后肯定边数是星的个数
    //因为每个星肯定唯一地代表一个星行一个星列的交点
 for (int j=0;j<m;j++)
  for (int i=0;i<n;i++)
   if (grid[i][j]=='*')
   {
    if (!i || grid[i-1][j]=='.')
      r++;
    bigraph[hash[i][j]][r-1]=1;
   }

    //开始跑二分算法
 int ans=0;
 memset (link,-1,sizeof (link));
    for (int i=0;i<l;i++)
 {
  memset(mark,0,sizeof (mark));
  if (can(i)) ans++;
 }
 printf("%d/n",ans);
 return 0;
}