zoukankan      html  css  js  c++  java
  • pku2226 Muddy Fields

    题意:Rc列的草地中有些泥坑,FJ想用一些木板将泥坑盖住,但是又不想盖住了草地,已知木板可以任意长。问怎样用最少的木板将所有泥坑盖住?

    分析:题意是很好理解,可是要想到二分匹配来做就难了,要想到那种构图的方法更是难上加难呀,太佩服了,这种构图方法反正我是怎么想也想不到的。

    因为不能盖住草地,所以在某一行有可能出现多个横着的木板,所以不能只用一个点来表示一行,而是有多个点。同样列不能只用一个点来表示一列。将连续的点当成一个点建图,一条边仍然表示的是一个有泥地的方格

    看题目中给的示例:

    *.*.
    .***
    ***.
    ..*.
    转换成下面来个这样的矩阵:

    1 0 2 0
    0 3 3 3
    4 4 4 0
    0 0 5 0

    ---------
    1 0 4 0
    0 3 4 5
    2 3 4 0
    0 0 4 0

    上面的矩阵是将每排连续的* 标记为一个点,下面的矩阵是将每列连续的*标记为一个点;这样,问题就可以转变为:俩个矩阵对应的非零位置,可以用横排覆盖也可以用纵列覆盖,例如(2,3)这个点,它可以被第一个矩阵中的3覆盖,也可以被第二个矩阵中的4覆盖,所以每一个非零的位置都是一个匹配,转变为求最小覆盖点集,也就是求出最大匹配,跟题目pku3041类似了

    pku 2226
    #include<iostream>
    using namespace std;
    int my[2555],mx[2555],r[255][255],c[255][255],nx,ny;
    bool vis[2555],mat[2555][2555];
    char g[51][51];
    int path(int s)
    {
    for(int y=1;y<=ny;y++)
    if(mat[s][y]&&!vis[y])
    {
    vis[y]
    =1;
    if(my[y]==-1||path(my[y]))
    {
    my[y]
    =s;
    return 1;
    }
    }
    return 0;
    }
    int Max_Match()
    {
    memset(my,
    -1,sizeof(my));
    memset(mx,
    -1,sizeof(mx));
    int ans=0;
    for(int i=1;i<=nx;i++)
    {
    if(mx[i]==-1)
    {
    memset(vis,
    0,sizeof(vis));
    ans
    +=path(i);
    }
    }
    return ans;
    }
    int main()
    {
    int n,m;
    scanf(
    "%d %d",&n,&m);
    for(int i=1;i<=n;i++)
    {
    getchar();
    for(int j=1;j<=m;j++)
    scanf(
    "%c",&g[i][j]);
    }
    nx
    =0;
    memset(r,
    0,sizeof(r));
    memset(c,
    0,sizeof(c));
    memset(mat,
    0,sizeof(mat));
    for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
    if(g[i][j]=='*')
    {
    nx
    ++;
    for(int k=j;g[i][k]=='*';k++)
    {
    r[i][k]
    =nx;
    j
    =k;
    }
    }
    ny
    =0;
    for(int j=1;j<=m;j++)
    for(int i=1;i<=n;i++)
    if(g[i][j]=='*')
    {
    ny
    ++;
    for(int k=i;g[k][j]=='*';k++)
    {
    c[k][j]
    =ny;
    i
    =k;
    }
    }
    for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
    {
    if(r[i][j]>0&&c[i][j]>0)
    mat[r[i][j]][c[i][j]]
    =1;
    }
    printf(
    "%d\n",Max_Match());
    return 0;
    }


     

     

  • 相关阅读:
    spring注解事务管理
    Spring切入点表达式常用写法
    JPA和事务管理
    maven仓库
    struts2拦截器
    js中 转义字符
    jquery中变量加$和不加$有什么区别!
    spring大乱炖
    第一章 java多线程
    CS:APP 05 笔记
  • 原文地址:https://www.cnblogs.com/nanke/p/2153261.html
Copyright © 2011-2022 走看看