POJ 3020 Antenna Placement

http://poj.org/problem?id=3020

  无向图的最小路径覆盖,问我们每两个相邻的城市可以共用一个无线,最少要多少个无线设备。

我们将每个城市编号,相邻的城市连一条边,每个城市都是X中的结点也是Y当中的结点,求出

最大匹配后,利用无向图最小路径覆盖的公式:顶点数 – 最大匹配 / 2 = 最小路径覆盖。

/*
Memory: 976K Time: 16MS
Language: C++ Result: Accepted
*/


#include<cstring>
#include<cstdio>
#include<cstdlib>
const int MAXD = 405;
int h, w, cnt;
bool map[MAXD][MAXD], vis[MAXD];
int yM[MAXD], xM[MAXD];
int id[45][15];

const int dx[] = { 0, 0, -1, 1};
const int dy[] = { 1, -1, 0, 0};

bool dfs( int u)
{
int v;
for( v = 1; v <= cnt; v ++)
if( map[u][v] && !vis[v])
{
vis[v] = true;
if( yM[v] == -1 || dfs( yM[v]))
{
yM[v] = u, xM[u] = v;
return true;
}
}
return false;
}

int MaxMatch()
{
int u, ret = 0;
memset( xM, -1, sizeof xM);
memset( yM, -1, sizeof yM);
for( u = 1; u <= cnt; u ++)
{
if( xM[u] == -1) {
memset( vis, false, sizeof vis);
if( dfs(u)) ret ++;
}
}
return ret;
}

int main()
{
int cas;
char s[15];
scanf( "%d\n", &cas);
while( cas --)
{
scanf( "%d%d", &h, &w);
memset( id, 0, sizeof id);
memset( map, false, sizeof map);
cnt = 0;
for( int i = 1; i <= h; i ++)
{
scanf( "%s", s + 1);
for( int j = 1; j <= w; j ++)
{
if( s[j] == '*')
id[i][j] = ++ cnt;
}
}
for( int i = 1; i <= h; i ++)
for( int j = 1; j <= w; j ++)
{
if( id[i][j] != 0)
for( int k = 0; k < 4; k ++)
{
int nx = i + dx[k];
int ny = j + dy[k];
if( id[nx][ny] != 0)
map[id[i][j]][id[nx][ny]] = true;
}
}

int ans = MaxMatch();
printf( "%d\n", cnt - ans / 2);
}
return 0;
}


你可能感兴趣的:(ant)