zoj 1654 中等二分匹配

来源:互联网 发布:淘宝运送方式怎么设置 编辑:程序博客网 时间:2024/06/07 23:34
解法1:我们可以把每个空地看成一个点 , 然后把所有有关联的空地之间连一条边 , 再求所得到的图的最大独立集 ,但是最大独立集是一个NP问题 , 因此并没有有效的算法 , 来求出这个。

解法2:分别把每一行、每一列看成是一个状态 , 最后求最大匹配

代码:
#include
#include
#include
#include
using namespace std;

#define maxn 2600
char ky[52][52];
int xs[52][52] , ys[52][52];
int pre[maxn] , cy[maxn];
vectorgrap[maxn];
int n , m;

void init()
{
    for(int i =1; i <= 2500 ; i++)
      grap[i].clear();
    memset(cy ,-1 , sizeof(cy));
    memset(xs ,0 ,  sizeof(xs));
    memset(ys ,0 , sizeof(ys));
}

int path(int u)
{
    for(int i =0; i < grap[u].size() ; i++)
    {
       int v =grap[u][i];
      if(!pre[v])
       {
          pre[v] =1;
          if(cy[v] ==-1 || path(cy[v]))
          {
             cy[v] =u;
             return1;
          }
       }
    }
    return0;
}

int maxmatch()
{
    int res =0;
    memset(cy ,-1 , sizeof(cy));
    for(int i =1; i <= n; i++)
    {
       memset(pre ,0 , sizeof(pre));
       res +=path(i);
    }

    returnres;

}

int main()
{
    int t;
   cin>>t;
    int gh =1;
   while(t--)
    {
       int x ,y;
      init();
       printf("Case:%d\n" , gh++);
       scanf("%d%d" , &x , &y);
       int i , j ,g , h;
       for(i = 0; i< x; i++)
          scanf("%s" ,ky[i]);
      
       n = 1 , m =1;
       h = 0;
       for(i = 0; i< x; i++)
       {
          g = 0;
          for(j = 0; j< y; j++)
          {
             if(ky[i][j]== 'o')  xs[i][j] = n , g = 1 , h = n;
             if(ky[i][j]== '#' && g)  n += 1 , g = 0;
          }

         if(g)  n += 1 , g = 0;
       }
       n = h , h =0;
       for(i = 0; i< y; i++)
       {
          g = 0;
          for(j = 0; j< x; j++)
          {
             if(ky[j][i]== 'o')  ys[j][i] = m , g = 1 , h = m;
             if(ky[j][i]== '#' && g)  m += 1 , g = 0;
          }

         if(g)  m += 1 , g = 0;
       }

       for(i = 0; i< x; i++)
          for(j = 0; j< y; j++)
             if(ky[i][j]== 'o')
             {
               grap[xs[i][j]].push_back(ys[i][j]);
             }
      
      //printf("Case :%d\n" , gh++);
      cout<<maxmatch()<<endl;
    }
    return0;
}
0 0
原创粉丝点击