poj3020 Antenna Placement (Hungary)

Posted by chet23 on Fri, 01 May 2020 05:18:32 +0200

Title Link

The key point of this problem is to build a map

At the beginning, I YY had at least three modeling methods
(for example, two points in a grid are packaged into a node of a bipartite graph, directly h*w nodes, and each row and column is a node.)

In fact, we need to change our way of thinking
Set the number of "*" in the grid to tt
We already know the worst: tt
If we set up a device in a grid, it is possible to save one device (the device can cover up to two points)
We can turn the problem into: the biggest savings

Construction drawing:
h*w points in each part
If the position is "*", then we will connect the four directions from x to ta respectively (the connected position must also be "*")
It means that if we place the device at this point, we can choose to save a device near ta

In this way, the biggest matching ans with Hungary is the biggest saving
But because every device is recalculated
So the final answer is: TT ans / 2


Thinking is very important in doing this kind of questions

Principle: if it is difficult, it will be reversed. If it is small, it will become large

Don't forget to initialize


using namespace std;

char s[50][12];
int n,h,z;
struct node{
    int y,nxt;
node way[200000];
int cx[500],cy[500],st[500],tot=0;
bool vis[500];

void add(int u,int w)

int get(int x,int y)
    return (x-1)*z+y;

int match(int x)
    for (int i=st[x];i;i=way[i].nxt)
        int y=way[i].y;
        if (!vis[y])
            if (!cy[y]||match(cy[y]))
                cx[x]=y; cy[y]=x;
                return 1;
    return 0;

int XYL()
    int ans=0;
    for (int i=1;i<=n;i++)
        if (!cx[i]){
    return ans;

int main()
    int T;
    while (T--)
        memset(st,0,sizeof(st)); tot=0;

        int tt=0;
        for (int i=1;i<=h;i++)

        for (int i=1;i<=h;i++)
            for (int j=1;j<=z;j++)
            if (s[i][j]=='*')
                int x=get(i,j);
                if (i>1&&s[i-1][j]=='*') add(x,get(i-1,j));
                if (i<h&&s[i+1][j]=='*') add(x,get(i+1,j));
                if (j>1&&s[i][j-1]=='*') add(x,get(i,j-1));
                if (j<z&&s[i][j+1]=='*') add(x,get(i,j+1));

    return 0;