poj 2226

来源:互联网 发布:centos png 编辑:程序博客网 时间:2024/06/16 13:39
题意:给出一个矩阵 , 每个点代表青草或者泥泞的路 , 问你最少要多少块木板(宽度为一个点的宽度 ,长度任意)才能把这些泥泞的路都盖住 , 并且不能把草盖住 , 木板可以重合 。

这题要是没加(不能把草盖住)这个条件 , 那么就是普通的最小路径覆盖 。
然而加了这个题之后 , 还是用最小路径覆盖 , 只不过要重新建过图。

最小路径覆盖 = 原图节点数 - 建图后的最大匹配 。
建图:分两步 , 1、从行开始 , 对么个点就行编号 , 如果在同一行并且相邻 , 那么就标记为一个编号 。
               2、从列开始 , 做法和1一样 , 行跟列是分别单独进行的 。
之后把行构成的点 , 看成是X点集合 , 列看成是Y点集合 , 再根据原图每个点的行跟列进行连接 , 就可以够成一个二分图。
最近就只要用最下路径覆盖就能求出了 。

代码:




#include
#include
#include
#include
#include
#include
using namespace std;

const int MAXN = 120;
int n , m ,  pre[2500] , lx[MAXN][MAXN] ,ly[MAXN][MAXN];
vectorgrap[2500];
bool s[2500];
int x , y;

void init()
{
    for(int i =0; i <= n; i++)
      grap[i].clear();
    memset(lx ,0 , sizeof(lx));
    memset(ly ,0, sizeof(ly));
}

bool can(int u)
{
    for(int i =0 ; i < grap[u].size(); i++)
    {
       int v =grap[u][i] ;
      if(!s[v])
       {
          s[v] =true;
          if(pre[v] ==-1 || can(pre[v]))
          {
             pre[v] =u;
             returntrue;
          }
       }
    }
    returnfalse;
}

int km()
{
    int sum =0;
    memset(pre ,-1 , sizeof(pre));
    for(int i =1; i < x; i++)
    {
       memset(s ,false , sizeof(s));
      if(can(i))  sum += 1;
    }
    returnsum;
}

int main()
{
   while(scanf("%d %d" , &n , &m) != EOF)
    {
      getchar();
      init();
       inti  ,j ;
       x = 1 , y =1;
       charcy[100][100];
       for(i = 0 ;i < n; i++)
       {
          scanf("%s" ,cy[i]);
          for(j = 0 ;j < m ; j++)
             if(cy[i][j]== '*')
             {
                for( ; j< m; j++)
                {
                   if(cy[i][j]== '*')  lx[i][j] = x;
                   else {x +=1; break;}
                }
                if(j ==m)  x += 1;
             }
       }
       for(i = 0 ;i < m; i++)
       {
          for(j = 0 ;j < n; j++)
             if(cy[j][i]== '*')
             {
                for(; j <n; j++)
                {
                   if(cy[j][i]== '*')  ly[j][i] = y;
                   else {y +=1; break;}
                }
                if(j ==n)  y += 1;
             }
       }
   
       for(i = 0; i< n; i++)
          for(j = 0 ;j < m; j++)
          {
            if(lx[i][j])  grap[lx[i][j]].push_back(ly[i][j]);
          }
      cout<<km()<<endl;
    }
    return0;
}


0 0
原创粉丝点击