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

相關文章
相關標籤/搜索