zoukankan      html  css  js  c++  java
  • zoj1654 Place the Robots 二分图最大匹配

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=654

    将每一行的包含空地的区域编号

    再将每一列的包含空地的区域编号

    然后把每一个横向块看作二部图中顶点的集合x中的顶点

    竖向块看作集合y中的顶点,若两个块有公共的空地,则将他们连边

    然后就转化为二分图最大匹配问题

    代码:

      1 #include<iostream>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<cstdio>
      5 using namespace std;
      6 
      7 #define maxn 51
      8 int xn,yn;
      9 int x[maxn*maxn],y[maxn*maxn];
     10 int xs[maxn][maxn],ys[maxn][maxn];
     11 int m,n;
     12 int g[maxn*maxn][maxn*maxn];
     13 int vis[maxn*maxn];
     14 char map[maxn][maxn];
     15 int ans;
     16 bool path(int u)
     17 {
     18    
     19    for(int v=1;v<=yn;v++)
     20   {
     21       if(g[u][v] && vis[v]==0)
     22       {
     23 
     24        vis[v]=1;
     25         if(y[v]==0 || path(y[v]))
     26        {
     27          x[u]=v;
     28          y[v]=u;
     29          return 1;
     30        }
     31       }
     32   }
     33   return 0;
     34 }void MaxMatch()
     35 {
     36   ans=0;
     37   memset(x,0,sizeof(x));
     38   memset(y,0,sizeof(y));
     39   for(int i=1;i<=xn;i++)
     40     if(!x[i])
     41     {
     42       memset(vis,0,sizeof(vis));
     43       if(path(i))
     44            ans++;
     45 
     46     }
     47     printf("%d
    ",ans);
     48 }
     49 int main()
     50 {
     51    int t;
     52   scanf("%d",&t);
     53   int iCase=0;
     54   while(t--)
     55   {
     56      printf("Case :%d
    ",++iCase);
     57 
     58 
     59 
     60      scanf("%d%d",&m,&n);
     61      memset(xs,0,sizeof(xs));
     62      memset(ys,0,sizeof(ys));
     63 
     64      for(int i=0;i<m;i++)
     65      scanf("%s",map[i]);
     66 
     67      int num=0;
     68      bool flag;
     69      for(int i=0;i<m;i++)//对水平方向的块进行编号
     70      {
     71          flag=0;
     72          for(int j=0;j<n;j++)
     73          {
     74            if(map[i][j]=='o')
     75               {
     76                  if(flag==0) num++;
     77                  xs[i][j]=num; flag=1;
     78               }
     79            else if(map[i][j]=='#') flag=0;
     80          }
     81     }
     82     xn=num;
     83     num=0;
     84 
     85     for(int j=0;j<n;j++)//对垂直方向的块进行编号
     86       {
     87           flag=0;
     88           for(int i=0;i<m;i++)
     89           {
     90             if(map[i][j]=='o')
     91             {
     92                 if(flag==0) num++;
     93                 ys[i][j]=num;flag=1;
     94             }
     95             else if(map[i][j]=='#') flag=0;
     96           }
     97       }
     98 
     99      yn=num;
    100 
    101      memset(g,0,sizeof(g));
    102 
    103      for(int i=0;i<m;i++)
    104      {
    105        for(int j=0;j<n;j++)
    106        {
    107            if(xs[i][j]) g[xs[i][j]][ys[i][j]]=1;
    108        }
    109      }
    110      MaxMatch();
    111 
    112   }
    113   return 0;
    114 }
  • 相关阅读:
    PHP与MySQL动态网站开发
    巧学巧用 Dreamweaver CS6制作网页
    PHP+MySQL网站开发全程实例
    电商店铺装修攻略
    代码 里面 跟 xib 里面要一致,不然 程序不知道 往东 往西了,
    这样2b的代码,
    controller的frame
    string的length不可能等于 0的,好吧,
    计算字体的高度时候,计算的字体要跟 xib 里面字体的大小 要一致的,不然计算的高度是没有意义的,
    关于 frame
  • 原文地址:https://www.cnblogs.com/xiaozhuyang/p/zoj1654.html
Copyright © 2011-2022 走看看