zoukankan      html  css  js  c++  java
  • POJ 3020 Antenna Placement(二分匹配最小路径覆盖)

    Description:

    The Global Aerial Research Centre has been allotted the task of building the fifth generation of mobile phone nets in Sweden. The most striking reason why they got the job, is their discovery of a new, highly noise resistant, antenna. It is called 4DAir, and comes in four types. Each type can only transmit and receive signals in a direction aligned with a (slightly skewed) latitudinal and longitudinal grid, because of the interacting electromagnetic field of the earth. The four types correspond to antennas operating in the directions north, west, south, and east, respectively. Below is an example picture of places of interest, depicted by twelve small rings, and nine 4DAir antennas depicted by ellipses covering them. 
     
    Obviously, it is desirable to use as few antennas as possible, but still provide coverage for each place of interest. We model the problem as follows: Let A be a rectangular matrix describing the surface of Sweden, where an entry of A either is a point of interest, which must be covered by at least one antenna, or empty space. Antennas can only be positioned at an entry in A. When an antenna is placed at row r and column c, this entry is considered covered, but also one of the neighbouring entries (c+1,r),(c,r+1),(c-1,r), or (c,r-1), is covered depending on the type chosen for this particular antenna. What is the least number of antennas for which there exists a placement in A such that all points of interest are covered? 

    Input:

    On the first row of input is a single positive integer n, specifying the number of scenarios that follow. Each scenario begins with a row containing two positive integers h and w, with 1 <= h <= 40 and 0 < w <= 10. Thereafter is a matrix presented, describing the points of interest in Sweden in the form of h lines, each containing w characters from the set ['*','o']. A '*'-character symbolises a point of interest, whereas a 'o'-character represents open space. 

    Output:

    For each scenario, output the minimum number of antennas necessary to cover all '*'-entries in the scenario's matrix, on a row of its own.

    Sample Input:

    2
    7 9
    ooo**oooo
    **oo*ooo*
    o*oo**o**
    ooooooooo
    *******oo
    o*o*oo*oo
    *******oo
    10 1
    *
    *
    *
    o
    *
    *
    *
    *
    *
    *
    

    Sample Output:

    17
    5

    题意:有一幅m*n的地图,这里面'*'代表城市,'o'代表空地,现在需要将所有的城市都接通网络,但是每条天线只能接通相邻的两个城市(上下左右),问最少需要多少这样的天线才能让所有的城市接通网络。

    可以看出每一条天线的接通就是一个匹配,若想求出最少的天线数目,即求出二分匹配中的最小路径覆盖:顶点数-最大匹配(由于该图为无向图,所以,最大匹配要除以2),首先要重新构图(以城市的数量为顶点,相邻的城市为边)。

    详细解释:http://www.cnblogs.com/13224ACMer/p/4666667.html

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    
    const int N=510;
    
    int G[N][N], vis[N], match[N], ans;
    int dir[4][2] = { {1,0}, {-1,0}, {0,1}, {0,-1} };
    char Map[N][N];
    
    int Find(int u)
    {
        int i;
    
        for (i = 1; i <= ans; i++)
        {
            if (!vis[i] && G[u][i])
            {
                vis[i] = 1;
    
                if (!match[i] || Find(match[i]))
                {
                    match[i] = u;
                    return 1;
                }
            }
        }
    
        return 0;
    }
    
    int main ()
    {
        int T, m, n, i, j, x, y, k, num, M[N][N];
    
        scanf("%d", &T);
    
        while (T--)
        {
            memset(G, 0, sizeof(G));
            memset(M, 0, sizeof(M));
            memset(match, 0, sizeof(match));
            ans = num = 0;
    
            scanf("%d%d", &m, &n);
            for (i = 0; i < m; i++)
                scanf("%s", Map[i]);
    
            for (i = 0; i < m; i++)
                for (j = 0; j < n; j++)
                    if (Map[i][j] == '*')
                        M[i][j] = ++ans; ///记录城市的标号及其坐标,ans表示城市的数量
    
            for (i = 0; i < m; i++)
            {
                for (j = 0; j < n; j++)
                {
                    if (M[i][j])
                    {
                        for (k = 0; k < 4; k++)
                        {
                            x = i + dir[k][0];
                            y = j + dir[k][1]; ///相邻的坐标
                            if (x >= 0 && x < m && y >= 0 && y < n && M[x][y]) ///本身是城市,且其相邻的点也是城市,则可以重新构图
                                G[M[i][j]][M[x][y]] = 1; ///重新构图
                        }
                    }
                }
            }
    
            for (i = 1; i <= ans; i++)
            {
                memset(vis, 0, sizeof(vis));
                if (Find(i)) num++;
            }
            num /= 2; ///该图为无向图,最大匹配除以2
    
            printf("%d
    ", ans-num); 
        }
    
        return 0;
    }
  • 相关阅读:
    hashlib模块
    configparser模块
    xml模块和shelve模块
    json与pickle模块
    3/30
    os模块
    sys模块
    shutil模块
    random模块
    2月书单《编码隐匿在计算机软硬件背后的语言》 13-16章
  • 原文地址:https://www.cnblogs.com/syhandll/p/4727212.html
Copyright © 2011-2022 走看看