zoukankan      html  css  js  c++  java
  • Poj 2446 Chessboard 匈牙利算法

    简介:这是Poj 2446 Chessboard 匈牙利算法的详细页面,介绍了和php,有关的知识、技巧、经验,和一些php源码等。

    class='pingjiaF' frameborder='0' src='http://biancheng.dnbcw.info/pingjia.php?id=343810' scrolling='no'>

    /*题意:给出一个矩形N*M棋盘,有K个格子是空洞,然后用2*1的矩形,对所有

    非空洞的格子进行覆盖,如果可以全部覆盖,就puts("YES");

    算法:建立二分图,用匈牙利算法;

    我们分别对所有的格子进行标号1.。。N*M

    将问题转化为二分图最大匹配问题。将棋盘按国际象棋棋盘那样添上黑白两种颜色,这样的话,黑色和白色的格子就构成了二分图的两个集合,即相邻的两个格子不会属于同个集合的。然后从上到下,从左到右对格子进行编号(除了洞),相邻的两格用边相连就构成一个二分图。然后求出最大匹配。。如果最大匹配+K=N*M就输出‘YES’。。

    */
    #include <iostream>
    using namespace std;

    #define MAX 32
    int map[MAX*MAX][MAX*MAX];
    int used[MAX*MAX][MAX*MAX];
    int id[MAX*MAX][MAX*MAX];
    int m,n,k,x,y;
    int mk[MAX*MAX] ;
    //从X集合中的顶点u出发用深度优先的策略寻找增广路
    //(这种增广路只能使当前的匹配数增加1)
    int nx, ny; //X和Y集合中顶点的个数
    int cx[MAX*MAX] , cy[MAX*MAX];
    //cx[i]表示最终求得的最大匹配中与Xi匹配的Y顶点, cy[i]同理
    int path(int u)
    {
     for(int v=0; v<ny; v++) //考虑所有Yi顶点v
     {
      if(map[u][v]&&!mk[v])
      {
       mk[v]=1;
       //如果v没有匹配,或者如果v已经匹配了,
       //但从y[v]出发可以找到一条增广路
       if(cy[v]==-1|| path(cy[v]))
       {
        cx[u] = v; //把v匹配给u
        cy[v] = u; //把u匹配给v
        return 1; //找到可增广路
       }
      }
     }
     return 0 ; //如果不存在从u出发的增广路
    }
    int MaxMatch() //求二部图最大匹配的匈牙利算法
    {
     int res=0;
     memset(cx,0xff,sizeof(cx)); //从0匹配开始增广
     memset(cy,0xff,sizeof(cy));
     for(int i=0; i<=nx; i++)
     {
      if(cx[i]==-1) //从每个未盖点出发进行寻找增广路
      {
       memset(mk,0,sizeof(mk));
       res+=path(i); //每找到一条增广路,可使得匹配数加1
      }
     }
     return res;
    }
    int main()
    {
     int i,j,k;
     while(scanf("%d%d%d",&m,&n,&k)!=EOF)
     {
     
      memset(map,0,sizeof(map));
      memset(used,0,sizeof(used));
      for(i=0;i<k;i++)
      {
       cin>>y>>x;
       used[x-1][y-1]=1;
      }
      int t=0;
      for(i=0;i<m;i++)
       for(j=0;j<n;j++)
        if(used[i][j]==0)//对没有涂黑的点进行标号。。
         id[i][j]=t++;
        for(i=0;i<m;i++)
         for(j=0;j<n;j++)
         {
          if(used[i][j]==0)//建图。。要注意边界问题;;
          {
           if(i-1>=0&&used[i-1][j]==0)
            map[id[i][j]][id[i-1][j]]=1;
           if(j-1>=0&&used[i][j-1]==0)
            map[id[i][j]][id[i][j-1]]=1;
           if(i+1<m&&used[i+1][j]==0)
            map[id[i][j]][id[i+1][j]]=1;
           if(j+1<n&&used[i][j+1]==0)
            map[id[i][j]][id[i][j+1]]=1;
          } 
         }
         nx=ny=t;
         int max=MaxMatch();
         if(max+k==n*m)
          cout<<"YES"<<endl;
         else
          cout<<"NO"<<endl;
     }
     return 0;
    }

    爱J2EE关注Java迈克尔杰克逊视频站JSON在线工具

    http://biancheng.dnbcw.info/php/343810.html pageNo:5
  • 相关阅读:
    接口测试工具-Jmeter使用笔记(五:正则表达式提取器)
    接口测试工具-Jmeter使用笔记(四:响应断言)
    接口测试工具-Jmeter使用笔记(三:管理请求服务器信息和Headers参数)
    接口测试工具-Jmeter使用笔记(二:GET/POST请求参数填写)
    接口测试工具-Jmeter使用笔记(一:运行一个HTTP请求)
    Centos6.5+Redmine
    【linux】扒站命令之利用wget快速扒站利用wget快速扒站
    【javascript】javascript设计模式mixin模式
    【vue】混合模式
    【小程序爬坑之路】获取地理位置信息
  • 原文地址:https://www.cnblogs.com/ooooo/p/2241966.html
Copyright © 2011-2022 走看看