Poj3020

来源:互联网 发布:软件 设计说明书 编辑:程序博客网 时间:2024/05/17 22:57
Antenna Placement
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 7174 Accepted: 3565

Description

The Global Aerial Research Centre has beenallotted the task of building the fifth generation of mobile phonenets in Sweden. The most striking reason why they got the job, istheir discovery of a new, highly noise resistant, antenna. It iscalled 4DAir, and comes in four types. Each type can only transmitand receive signals in a direction aligned with a (slightly skewed)latitudinal and longitudinal grid, because of the interactingelectromagnetic field of the earth. The four types correspond toantennas operating in the directions north, west, south, and east,respectively. Below is an example picture of places of interest,depicted by twelve small rings, and nine 4DAir antennas depicted byellipses covering them. 
Poj <wbr>3020 
Obviously, it is desirable to use as few antennas as possible, butstill provide coverage for each place of interest. We model theproblem as follows: Let A be a rectangular matrix describing thesurface of Sweden, where an entry of A either is a point ofinterest, which must be covered by at least one antenna, or emptyspace. Antennas can only be positioned at an entry in A. When anantenna is placed at row r and column c, this entry is consideredcovered, but also one of the neighbouring entries(c+1,r),(c,r+1),(c-1,r), or (c,r-1), is covered depending on thetype chosen for this particular antenna. What is the least numberof antennas for which there exists a placement in A such that allpoints of interest are covered? 

Input

On the first row of input is a single positiveinteger n, specifying the number of scenarios that follow. Eachscenario begins with a row containing two positive integers h andw, with 1 <= h <= 40 and 0 < w <= 10. Thereafter is amatrix presented, describing the points of interest in Sweden inthe form of h lines, each containing w characters from the set['*','o']. A '*'-character symbolises a point of interest, whereasa 'o'-character represents open space. 

Output

For each scenario, output the minimum number ofantennas necessary to cover all '*'-entries in the scenario'smatrix, on a row of its own.

Sample Input

27 9ooo**oooo**oo*ooo*o*oo**o**ooooooooo*******ooo*o*oo*oo*******oo10 1***o******

Sample Output

175
分析:
    稍作分析不难发现,要使基站最少,则匹配数最大,证明在这里就略过了,图建好之后就是一遍dinic无压力
代码:
#include
#include
#include
#include
#include
using namespace std;
int map[40][40];
int n,m;
const
 int 
 INF=1<<30;
int head[1000],next[4000],end,start=0,from[4000],to[4000],cap[4000],flow[4000];
bool is_start(int x,int y)
 {
         return 0==(x-y)%2;//0 1
 }
int sum,side=1;
void read()
{
     string s1;
     scanf("%d%d",&n,&m);
     int i,j,k,l;
   for(i=1;i<=n;i++)
         {
               getline(cin,s1);  
              for(j=1;j<=m;j++)
             {
                 if(s1[j-1]=='*')
                                   map[i][j]=++sum;
                 else
                     map[i][j]=-1;
                }
     }
            end=++sum;   
   for(i=1;i<=n;i++)
     for(j=1;j<=m;j++)
    {
        if(map[i][j]!=-1)
                  {
                         if(is_start(i,j))
                           {
                               next[++side]=head[0];
                               head[0]=side;
                               to[side]=map[i][j];
                                 from[side]=0;
                               cap[side]=1;
                                
                                    next[++side]=head[map[i][j]];
                               head[map[i][j]]=side;
                               to[side]=0;
                                 from[side]=map[i][j];
                               cap[side]=0;
                                
                                     if(i+1<=n&&map[i+1][j]!=-1)
                                   {
                                            next[++side]=head[map[i][j]];
                                                 head[map[i][j]]=side;
                                                 to[side]=map[i+1][j];
                                                 from[side]=map[i][j];
                                                 cap[side]=1;
                                                  next[++side]=head[map[i+1][j]];
                                               head[map[i+1][j]]=side;
                                               to[side]=map[i][j];
                                           from[side]=map[i+1][j];
                                               cap[side]=0;
                                        }
                                if(i-1>=1&&map[i-1][j]!=-1)
                                   {
                                            next[++side]=head[map[i][j]];
                                                 head[map[i][j]]=side;
                                                 to[side]=map[i-1][j];
                                                 from[side]=map[i][j];
                                                 cap[side]=1;
                                                  next[++side]=head[map[i-1][j]];
                                               head[map[i-1][j]]=side;
                                               to[side]=map[i][j];
                                           from[side]=map[i-1][j];
                                               cap[side]=0;
                                        }
                                  if(j+1<=m&&map[i][j+1]!=-1)
                                        {
                                            next[++side]=head[map[i][j]];
                                                 head[map[i][j]]=side;
                                                 to[side]=map[i][j+1];
                                                 from[side]=map[i][j];
                                                 cap[side]=1;
                                                  next[++side]=head[map[i][j+1]];
                                               head[map[i][j+1]]=side;
                                               to[side]=map[i][j];
                                           from[side]=map[i][j+1];
                                               cap[side]=0;
                                        }
                                    if(j-1>=1 &&map[i][j-1]!=-1)
                                    {
                                            next[++side]=head[map[i][j]];
                                                 head[map[i][j]]=side;
                                                 to[side]=map[i][j-1];
                                                 from[side]=map[i][j];
                                                 cap[side]=1;
                                                  next[++side]=head[map[i][j-1]];
                                               head[map[i][j-1]]=side;
                                               to[side]=map[i][j];
                                           from[side]=map[i][j-1];
                                               cap[side]=0;
                                        }
                       }
                    
          
            else 
             {
                  next[++side]=head[map[i][j]];
                                   head[map[i][j]]=side;
                             to[side]=end;
                             from[side]=map[i][j];
                             cap[side]=1;
                           next[++side]=head[end];
                                head[end]=side;
                                to[side]=map[i][j];
                            from[side]=end;
                                cap[side]=0;
              }
                         
                   }
        }                  
}
int h[1000];
bool visited[1001];
int line [1001];
bool BFS()
{
     int left,right,l,r,i,j,k;
       visited[start]=true;
   line[1]=start;
         h[start]=1;
    left=1;
        right=1;
         while(left<=right)
     {
                  l=left%(sum+1);
                  r=right%(sum+1);
                 j=head[line[l]];
                   while(j!=0)
              {
                       if(!visited[to[j]]&&cap[j]>flow[j])
                           {
                           h[to[j]]=h[line[l]]+1;
                         line[(++right)%(sum+1)]=to[j];
                         visited[to[j]]=true;
                          }
                        j=next[j];
                  }
            left++;
            }
        return visited[end];
}
int DFS(int x,int now)
 {
        int a=now;
       int i,j,k,l;
         j=head[x];
           if(x==end||now==0)
            return now;
        while(j!=0)
           {
             if(cap[j]>flow[j]&&h[to[j]]==h[from[j]]+1)
              {        l=DFS(to[j],min(a,cap[j]-flow[j])) ;
            a-=l;
                   flow[j]+=l;
             flow[j^1]-=l;
                   if(a==0)
                  return now; 
                 }         
               j=next[j];
             }
       return now-a;
 }
void find()
{
   int ans=0;
     while(BFS()) 
  {
         
           ans+=DFS(start,INF);
            memset(visited,false,sizeof(visited));
            memset(h,0,sizeof(h));
     memset(line,0,sizeof(line));
    }
      int j=head[start];
     while(j!=0)
     {
      if(flow[j]==0)
     ans++;
           j=next[j]; 
     }
    j=head[end];
   while(j!=0)
     {
       if(flow[j]==0)
             ans++;   
          j=next[j];
       }
   printf("%d\n",ans);
}
int main()
{
        freopen("std.in","r",stdin);
   freopen("self.out","w",stdout);
         int i,k;
      scanf("%d",&k);
        for(i=1;i<=k;i++)
   {
         memset(head,0,sizeof(head));
         memset(next,0,sizeof(next));
         memset(flow,0,sizeof(flow));
         memset(cap,0,sizeof(cap));
           memset(map,0,sizeof(map));
           memset(to,0,sizeof(to));
     memset(from,0,sizeof(from));
    read();      
       find();
   }
     return 0;
}

0 0
原创粉丝点击