zoukankan      html  css  js  c++  java
  • poj 2226

    题意:一个由r行c列方格组成的田地,里面有若干个方格充满泥泞,其余方格都是草。要用长度不限,宽度为1的长木板来覆盖这些泥方格,但不能覆盖草地。最少要用多少个长木板?

    分析:由于不能覆盖草地,这道题显得相当难。看别人的题解看了很久才明白它是如何跟二分匹配联系在一起的。这个建图实在是精妙。我们先把同一行每一段连续的泥方格作为一个顶点(其实就是一个长木板),这些顶点放进去集合x;而同一列每一段连续的泥方格也作为一个顶点,放进集合y。a∈x,b∈y,a,b若有相交则建一条边(a,b)。巧妙之处就在这条边,每条边所表示的就是原来的图中的一个泥方格,边与泥方格存在一一对应关系。若选了a(a∈x或a∈y)木板,则所有与a关联的边所表示的泥方格都会被覆盖。所以现在的问题就变成,求这个二分图的最小点覆盖数。由公式:最小点覆盖数=最大匹配数,即可知只要求最大匹配就OK。

    另外,这道题坑爹之处是,图的大小不止50*50

    View Code
     1 #include<cstdio>
     2 bool matrix[500][500],visited[500];
     3 char map[501][501];
     4 int r,c,mat[2][500],set[500][500],nx,ny;
     5 int path(int u)
     6 {
     7     int i;
     8     for(i=0;i<ny;i++)
     9     {
    10         if(matrix[u][i] && !visited[i])
    11         {
    12             visited[i]=true;
    13             if(mat[1][i]==-1 || path(mat[1][i]))
    14             {
    15                 mat[0][u]=i;
    16                 mat[1][i]=u;
    17                 return 1;
    18             }
    19         }
    20     }
    21     return 0;
    22 }
    23 int Hungary()
    24 {
    25     int ans=0,i,j;
    26     for(i=0;i<nx;i++)
    27         mat[0][i]=-1;
    28     for(i=0;i<ny;i++)
    29         mat[1][i]=-1;
    30     for(i=0;i<nx;i++)
    31     {
    32         for(j=0;j<ny;j++)
    33             visited[j]=false;
    34         ans+=path(i);
    35     }
    36     return ans;
    37 }
    38 int main()
    39 {
    40     int i,j;
    41     while(~scanf("%d%d%*c",&r,&c))
    42     {
    43         for(i=0;i<r;i++)
    44         {
    45             for(j=0;j<c;j++)
    46                 matrix[i][j]=false;
    47         }
    48         for(i=0;i<r;i++)
    49             gets(map[i]);
    50         nx=0;
    51         for(i=0;i<r;i++)
    52         {
    53             for(j=0;j<c;j++)
    54             {
    55                 if(map[i][j]=='*')
    56                 {
    57                     while(j<c && map[i][j]=='*')
    58                         set[i][j++]=nx;
    59                     nx++;
    60                 }
    61             }
    62         }
    63         ny=0;
    64         for(j=0;j<c;j++)
    65         {
    66             for(i=0;i<r;i++)
    67             {
    68                 if(map[i][j]=='*')
    69                 {
    70                     while(i<r && map[i][j]=='*')
    71                         matrix[set[i++][j]][ny]=true;
    72                     ny++;
    73                 }
    74             }
    75         }
    76         printf("%d\n",Hungary());
    77     }
    78     return 0;
    79 }
  • 相关阅读:
    express中间件原理 && 实现
    vue、react、angular三大框架对比 && 与jQuery的对比
    javascript数据基本类型和引用类型区别详解
    HTML页面的重绘(repaint)和重流(reflow)
    web worker原理 && SSE原理
    C++ STL 初探
    JavaScript模块化 --- Commonjs、AMD、CMD、es6 modules
    nodejs(三) --- nodejs进程与子进程
    数学图形之海螺与贝壳
    数学图形之螺旋管
  • 原文地址:https://www.cnblogs.com/ZShogg/p/2954740.html
Copyright © 2011-2022 走看看