# poj3020 Antenna Placement (Hungary)

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

analysis:
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

# tip

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

```#include<cstdio>
#include<cstring>
#include<iostream>

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];

{
tot++;
way[tot].y=w;way[tot].nxt=st[u];st[u]=tot;
}

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])
{
vis[y]=1;
if (!cy[y]||match(cy[y]))
{
cx[x]=y; cy[y]=x;
return 1;
}
}
}
return 0;
}

int XYL()
{
memset(cx,0,sizeof(cx));
memset(cy,0,sizeof(cy));
int ans=0;
for (int i=1;i<=n;i++)
if (!cx[i]){
memset(vis,0,sizeof(vis));
ans+=match(i);
}
return ans;
}

int main()
{
int T;
scanf("%d",&T);
while (T--)
{
memset(st,0,sizeof(st)); tot=0;
scanf("%d%d",&h,&z);

n=h*z;
int tt=0;
for (int i=1;i<=h;i++)
scanf("%s",s[i]+1);

for (int i=1;i<=h;i++)
{
for (int j=1;j<=z;j++)
if (s[i][j]=='*')
{
tt++;
int x=get(i,j);