POJ-3020-Antena Placement(最小路径覆盖)

链接:

https://vjudge.net/problem/POJ-3020

题意:

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?

思路:

对每个兴趣点标号,相邻的进行配对,再找最大匹配,答案则是总点数减去最大匹配一半。
因为是五向图,所有最大匹配是成功匹配的所有点数,除2正好是对数,而每一对只需一个就可以覆盖。
所有res = cnt-sum/2。

代码:

#include <iostream>
#include <cstdio>
#include <vector>
#include <memory.h>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
#include <math.h>
using namespace std;
const int MAXN = 500;
const int INF = 1<<30;
int Next[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};

char Map[MAXN][MAXN];
int Dis[MAXN][MAXN];
vector<int> G[MAXN*MAXN];
int Linked[MAXN], Vis[MAXN];
int n, m, cnt;

bool Dfs(int x)
{
    for (int i = 0;i < G[x].size();i++)
    {
        int node = G[x][i];
        if (Vis[node])
            continue;
        Vis[node] = 1;
        if (Linked[node] == -1 || Dfs(Linked[node]))
        {
            Linked[node] = x;
            return true;
        }
    }
    return false;
}

int Solve()
{
    memset(Linked, -1, sizeof(Linked));
    int sum = 0;
    for (int i = 1;i <= cnt;i++)
    {
        memset(Vis, 0, sizeof(Vis));
        if (Dfs(i))
            sum++;
    }
    return sum;
}

int main()
{
    int t;
    scanf("%d", &t);
    while (t--)
    {
        cnt = 0;
        scanf("%d%d", &n, &m);
        for (int i = 1;i <= n;i++)
            scanf("%s", Map[i]+1);
        for (int i = 1;i <= n;i++)
        {
            for (int j = 1;j <= m;j++)
                if (Map[i][j] == '*')
                    Dis[i][j] = ++cnt;
        }
        for (int i = 1;i <= cnt;i++)
            G[i].clear();
        for (int i = 1;i <= n;i++)
        {
            for (int j = 1;j <= m;j++)
                if (Map[i][j] == '*')
                {
                    for (int k = 0;k < 4;k++)
                    {
                        int tx = i+Next[k][0];
                        int ty = j+Next[k][1];
                        if (tx < 1 || tx > n || ty < 1 || ty > m)
                            continue;
                        if (Map[tx][ty] == '*')
                            G[Dis[i][j]].push_back(Dis[tx][ty]);
                    }
                }
        }
        int sum = Solve();
//        cout << sum << endl;
        cout << cnt-sum/2 << endl;
    }

    return 0;
}

猜你喜欢

转载自www.cnblogs.com/YDDDD/p/11164464.html
今日推荐