poj Antenna Placement(最小边覆盖数)

题意:一个矩阵中有一些点,用1*2的小矩阵覆盖这些点,求需要的最少小矩阵数;

参考:http://blog.csdn.net/lyy289065406/article/details/6647040

思路:无向图最小边覆盖数=顶点数-最大匹配数/2;

        将每个待匹配的点用一个唯一的数字表示,相当于离散化,便于建图;

        每个待匹配的点与相邻点建边;

        由于建图是将矩阵作为二分图,一个点被拆成了两个点,因此最大匹配数要除二;

        由于未匹配的点也需要覆盖,因此结果为顶点数-最大匹配数/2;

#include<cstdio>

#include<cstring>

#include<cmath>

#include<algorithm>

using namespace std;

int n,m,t,cnt;

char temp;

int mm[550][550];

int vis[5050],link[5005];

int mark[505][550];

int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};

int dfs(int x)

{

    for(int i=1;i<=cnt;i++){

       if(!vis[i]&&mark[x][i]){

         vis[i]=1;

         if(link[i]==-1||dfs(link[i]))

         {

             link[i]=x;

             return 1;

         }

       }

    }

    return 0;

}

int hungary()

{

    int sum=0;

    memset(link,-1,sizeof(link));

    for(int i=1;i<=cnt;i++){

      memset(vis,0,sizeof(vis));

       if(dfs(i)) sum++;

    }

    return sum;

}

int main()

{

    int ans,i,j,k;

    while(scanf("%d",&t)!=EOF)

    {

        while(t--)

        {

            cnt=0;

            memset(mm,0,sizeof(mm));

            memset(mark,0,sizeof(mark));

            scanf("%d%d",&n,&m);

            for(i=0;i<n;i++)

            {

                for(j=0;j<m;j++)

                {

                    scanf(" %c",&temp);

                    if(temp=='*'){

                        mm[i][j]=++cnt;//每个点用数字表示

                    }

                }

            }

            for(i=0;i<n;i++)

            {

                for(j=0;j<m;j++)

                {

                    if(mm[i][j])

                    for(k=0;k<4;k++){

                       int xx=i+dir[k][0];

                       int yy=j+dir[k][1];

                       if(mm[xx][yy]&&xx>=0&&yy>=0&&xx<n&&yy<m){ //相邻建边

                          mark[mm[xx][yy]][mm[i][j]]=1;

                          mark[mm[i][j]][mm[xx][yy]]=1;

                       }

                    }

                }

            }

            printf("%d\n",cnt-hungary()/2);

        }

    }

    return 0;

}

 

你可能感兴趣的:(ant)