POJ3020深度解析(二分图--最小路径覆盖)

题目:Antenna Placement

 

题意:

一个矩形中,有N个城市’*’,现在这n个城市都要覆盖无线,若放置一个基站,那么它至多可以覆盖相邻的两个城市。

问至少放置多少个基站才能使得所有的城市都覆盖无线?

看本题更详细解法,请戳这里。

 

#include <iostream>
#include <string.h>

#define N 1150

int linker[N];
bool used[N];
int map[N][N];
int g[N][N];

int uN,vN;

int dire_r[4]={-1,1,0,0};
int dire_c[4]={0,0,-1,1};

bool DFS(int u)
{
    int v;
    for(v=1;v<=vN;v++)
    {
        if(g[u][v]&&!used[v])
        {
            used[v]=true;
            if(linker[v]==-1||DFS(linker[v]))
            {
                linker[v]=u;
                return true;
            }
        }
    }
    return false;
}

int Hungary()
{
    int u;
    int ret=0;
    memset(linker,-1,sizeof(linker));
    for(u=1;u<=uN;u++)
    {
        memset(used,false,sizeof(used));
        if(DFS(u))   ret++;
    }
    return ret;
}

int main()
{
    char ch;
    int n,m,t;
    int i,j,k,p;
    std::cin>>t;
    while(t--)
    {
        p=0;
        std::cin>>n>>m;
        memset(g,0,sizeof(g));
        memset(map,0,sizeof(map));
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=m;j++)
            {
              std::cin>>ch;
              if(ch=='*')
                 map[i][j]=++p;
            }
        }
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=m;j++)
            {
                if(map[i][j])
                {
                    for(k=0;k<4;k++)
                    {
                        int x=i+dire_r[k];
                        int y=j+dire_c[k];
                        if(map[x][y])
                            g[map[i][j]][map[x][y]]=1;
                    }
                }
            }
        }
        uN=vN=p;
        int ans=Hungary();
        std::cout<<uN-ans/2<<std::endl;
    }
    return 0;
}


 

你可能感兴趣的:(POJ3020深度解析(二分图--最小路径覆盖))