POJ 3020 Antenna Placement 解题报告

    题意就不说了,求二部图最大匹配。spa

    问题是怎么建图……code

    给定的条件中,h<40,w<10,因此笔者直接默认全部状况的地图都是40*10,固然,超出范围的即是空城o。blog

    而后给城市编号。一个城市只能和上下左右4个城市公用天线。换个换说就像国际象棋的棋盘同样,黑色格子与白色格子天然分红了二部图。黑色只能和白色匹配。string

    编号也很简单了。从第一行开始,第一格是黑色城市1,而后白色城市1,而后黑色城市2,白色城市2……由于全部的图都默认同样大小,因此编号能够重用。io

    为了方便知道(i,j)究竟是黑色仍是白色,咱们能够用正数编号表示黑色,负数编号表示白色。class

    而后求最大匹配,直接匈牙利过去就行了。地图

    贴代码,0MSdi

#include <cstdio>
#include <cstring>

const int maxn=201;
bool mp[maxn][maxn];
bool vis[maxn];
int link[maxn];
int No[41][10];
int n;

bool DFS(int x)
{
    for(int y=1;y<=n;y++)
    {
        if(mp[x][y] && !vis[y])
        {
            vis[y]=true;
            if(link[y]==0 || DFS(link[y]))
            {
                link[y]=x;
                return true;
            }
        }
    }
    return false;
}

int maxMartch()
{
    int count=0;
    for(int x=1;x<=n;x++)
    {
        memset(vis,0,sizeof(vis));
        if(DFS(x))
            count++;
    }
    return count;
}

int main()
{
    int T;
    scanf("%d",&T);

    int index=2;
    for(int i=0;i<40;i++)
        for(int j=0;j<10;j++,index++)
            No[i][j]=(index/2)*((index+i)%2?-1:1);
    n=200;

    while(T--)
    {
        int num=0;
        int w,h;
        scanf("%d%d",&h,&w);
        if(w%2)
            w++;

        char str[2][20];
        memset(mp,0,sizeof(mp));
        memset(link,0,sizeof(link));
        memset(str,0,sizeof(str));
        for(int i=0;i<h;i++)
        {
            scanf("%s",str[i&1]);
            if(str[i&1][0]=='*')
            {
                num++;
                if(str[1-i&1][0]=='*')
                {
                    if(No[i][0]>0)
                        mp[No[i][0]][-No[i-1][0]]=true;
                    else
                        mp[No[i-1][0]][-No[i][0]]=true;
                }
            }
            for(int j=1; j<w; j++)
            {
                if(str[i&1][j]=='*')
                {
                    num++;
                    if(str[i&1][j-1]=='*')
                    {
                        if(No[i][j]>0)
                            mp[No[i][j]][-No[i][j-1]]=true;
                        else
                            mp[No[i][j-1]][-No[i][j]]=true;
                    }

                    if(str[1-i&1][j]=='*')
                    {
                        if(No[i][j]>0)
                            mp[No[i][j]][-No[i-1][j]]=true;
                        else
                            mp[No[i-1][j]][-No[i][j]]=true;
                    }
                }
            }
        }
        printf("%d\n",num-maxMartch());
    }
}

    整个建图是本身想的,好像略似繁琐……不过还好,比赛的时候估计也能这么想到吧。vi

相关文章
相关标签/搜索