POJ-3020-Antenna Placement [二分匹配][最小路径覆盖]

来源:互联网 发布:星际争霸剧情知乎 编辑:程序博客网 时间:2024/05/25 16:38

题目传送门


题意:一个地图由o*组成,一个信号塔可以覆盖两个连续的*。问至少需要多少个信号塔才能覆盖所有的*

思路:先将所有的’*’hash,然后建立二分图,用匈牙利算法算出最大匹配数。最小路径覆盖数 = 顶点数 - 最大匹配数

#include <algorithm>#include <iostream>#include <cstdlib>#include <cstring>#include <cstdio>#include <cmath>#include <queue>#include <stack>#include <map>#include <set>using namespace std;bool path[410][410], used[410];int match[410];int num;bool Dfs(int x){    for (int i = 1; i <= num; i++)    {        if (!used[i] && path[x][i])        {            used[i] = true;            if (!match[i] || Dfs(match[i]))            {                match[i] = x;                return true;            }        }    }    return false;}int Matching(){    int ans = 0;    memset(match, 0, sizeof(match));    for (int i = 1; i <= num; i++)    {        memset(used, false, sizeof(used));        if (Dfs(i))        {            ans++;        }    }    return ans;}int main(void){    //freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    int T;    scanf("%d", &T);    while (T--)    {        int n,m;        int a[50][20];        char mp[50][20];        memset(a,0,sizeof(a));        memset(path,false,sizeof(path));        memset(mp, 0, sizeof(mp));        num = 1;        scanf("%d %d", &n, &m);        for (int i = 0; i < n; i++)            scanf(" %s", mp[i]);        for (int i = 0; i < n; i++)            for (int j = 0; j < m; j++)                if (mp[i][j]=='*')                    a[i][j] = num++;        for (int i = 0; i < n; i++)        {            for (int j = 0; j < m; j++)            {                if (a[i][j])                {                    if (i-1>=0 && a[i-1][j])                        path[a[i][j]][a[i-1][j]] = true;                    if (i+1<n && a[i+1][j])                        path[a[i][j]][a[i+1][j]] = true;                    if (j-1>=0 && a[i][j-1])                        path[a[i][j]][a[i][j-1]] = true;                    if (j+1<m && a[i][j+1])                        path[a[i][j]][a[i][j+1]] = true;                }            }        }        num--;        int ans = Matching();        printf("%d\n", num-ans/2);    }    return 0;}
阅读全文
0 0