poj 3020 Antenna Placement

来源:互联网 发布:java 变量类型 编辑:程序博客网 时间:2024/06/11 06:06

题意:给出一个图,用最少的椭圆覆盖所有的点,一个椭圆最多覆盖两个点,纵向或横向。
分析:贪心,尽可能使椭圆覆盖两个点,所以答案就是 点数 - 最大匹配数。

#include <cstdio>#include <cstring>#include <vector>using namespace std;int np, n, m, p[450];int ind[50][50];char s[50][50];bool vis[450];vector<int>h[450];bool find(int u){    for(int i = 0; i < h[u].size(); i++)    {        int v = h[u][i];        if(!vis[v])        {            vis[v] = true;            if(p[v] == -1 || find(p[v]))            {                p[u] = v;                p[v] = u;                return true;            }        }    }    return false;}int MaxMatch(){    int ans = 0;    memset(p, -1, sizeof(p));    for(int i = 0; i < np; i++)    {        if(p[i] == -1)         {            memset(vis, false, sizeof(vis));            ans += find(i);        }    }    return ans;}int main(){    int t;    scanf("%d", &t);    while(t--)    {        scanf("%d%d", &n, &m);        np = 0;        for(int i = 0; i < n; i++)         {            scanf("%s", s[i]);            for(int j = 0; j < m; j++)            {                if(s[i][j] == '*')                {                    ind[i][j] = np++;                    if(j && s[i][j-1] == '*')                    {                        h[ind[i][j]].push_back(ind[i][j-1]);                        h[ind[i][j-1]].push_back(ind[i][j]);                    }                    if(i && s[i-1][j] == '*')                    {                         h[ind[i][j]].push_back(ind[i-1][j]);                        h[ind[i-1][j]].push_back(ind[i][j]);                    }                }            }        }        printf("%d\n", np - MaxMatch());        for(int i = 0; i < np; i++) h[i].clear();    }    return 0;}
0 0