POJ 3020题

类型:二分匹配
题目大意:一个矩形中,有N个城市,现在这n个城市都要覆盖无线,若放置一个基站,那么它至多可以覆盖相邻的两个城市。
问至少放置多少个基站才能使得所有的城市都覆盖无线?
解题思路:最大匹配数+城市总数-(最大匹配数*2) ,最大匹配数代表每个基站覆盖两个城市,其余的城市用一个基站覆盖
其中最大匹配数的求解,对顶点数不分左右子集,将左右子集都等于所有定点,最后将得出的匹配除以二则得到真正的匹配
二分图的构造是对*编号,然后给相邻的*连双向边,对*构造二分图 
最大匹配:使用匈牙利算法
从这道题得出了一个结论:所有顶点的匹配等于左右子集匹配的2倍
#include <iostream>
#include <string>
//#include <conio.h>
using namespace std;
int h,w;
#define arraysize 401
#define hsize 41
#define wsize 11
int map[arraysize][arraysize];
bool final[arraysize];
int match[arraysize];
string tempmap[hsize];
int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};         //定义4个方向
bool DFS(int p)
{
     int i;
     int temp;
     for(i=0;i<h*w;++i)
     {
        if(map[p][i] && !final[i])
        {
           final[i] = true;
           temp = match[i];
           match[i] = p;
           if(temp==0 || DFS(temp)) return true;
           match[i] = temp;
        }
     }
     return false;
}
int mat()
{
    int i,j;
    int maxmatch = 0;
    for(i=0;i<h*w;++i)
    {
       memset(final,0,sizeof(final));
       if(DFS(i))  maxmatch++;
    }
    return maxmatch;
}
int main()
{
    //freopen("1.txt","r",stdin);
    int t;
    int i,j,k,e;
    string str;
    int total;
    cin>>t;
    while(t--)
    {
       total=0;
       memset(map,0,sizeof(map));
       memset(match,0,sizeof(match));
       cin>>h>>w;
       for(i=0;i<h;++i)  //i行
       {
          cin>>tempmap[i];
       }
       for(i=0;i<h;++i)  //i行
       {
          for(j=0;j<w;++j)        //j列
          {
             if(tempmap[i][j]=='*')
             {
                total++;
                for(k=0;k<4;++k)
                {
                    int tempr = i+dir[k][0];
                    int tempc = j+dir[k][1];
                    if(tempr>=0 && tempr <h && tempc>=0 && tempc<w && tempmap[tempr][tempc]=='*')
                    {
                       map[i*w+j][tempr*w+tempc] = 1;
                    }                  
                }
             }
          }
       }
       cout<<(total-mat()/2)<<endl;
    }
    //getch();
    return 0;
}

posted @ 2010-05-06 22:44  北海小龙  阅读(340)  评论(0编辑  收藏  举报