• [POJ] 3020 Antenna Placement(二分图最大匹配)


    题目地址:http://poj.org/problem?id=3020

    输入一个字符矩阵,'*'可行,'o'不可行。因为一个点可以和上下左右四个方向的一个可行点组成一个集合,所以对图进行黑白染色(每个点的值为其横纵坐标之和),然后就可划分为二分图,进行最大匹配。最后最大匹配数加剩下的单个点数量即为所求。

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<string.h>
      4 #include<algorithm>
      5 #include<math.h>
      6 #include<stdbool.h>
      7 #include<time.h>
      8 #include<stdlib.h>
      9 #include<set>
     10 #include<map>
     11 #include<stack>
     12 #include<queue>
     13 #include<vector>
     14 using namespace std;
     15 #define clr(x,y)    memset(x,y,sizeof(x))
     16 #define sqr(x)      ((x)*(x))
     17 #define rep(i,a,b)  for(int i=(a);i<=(b);i++)
     18 #define LL          long long
     19 #define INF         0x3f3f3f3f
     20 #define A           first
     21 #define B           second
     22 #define PI          acos(-1.0)
     23 const int N=2000+131;
     24 const int dx[4]={0,0,-1,1};
     25 const int dy[4]={1,-1,0,0};
     26 int n,m,k,num,k1,k2,f[N],g[N][N],link[N],flag[N][N],b[N],c[N];
     27 char a[N][N];
     28 
     29 void init()
     30 {
     31     clr(f,0);
     32     clr(g,0);
     33     clr(link,-1);
     34     clr(flag,0);
     35     clr(b,0);
     36     clr(c,0);
     37     num=0;
     38     k1=0;
     39     k2=0;
     40 }
     41 
     42 bool find(int x)
     43 {
     44     for(int i=0;i<k2;i++) {
     45         if(!f[c[i]] && g[x][c[i]]) {
     46             f[c[i]]=1;
     47             if(link[c[i]]==-1 || find(link[c[i]])) {
     48                 link[c[i]]=x;
     49                 return true;
     50             }
     51         }
     52     }
     53     
     54     return false;
     55 }
     56 
     57 int hungary()
     58 {
     59     int ans=0;
     60     for(int i=0;i<k1;i++) {
     61         clr(f,0);
     62         if(find(b[i])) ans++;
     63     }
     64     
     65     return ans;
     66 }
     67 
     68 int main()
     69 {
     70     int u,v,cas;
     71     
     72     scanf("%d",&cas);
     73     while(cas--) {
     74         init();
     75         scanf("%d%d",&m,&n);
     76         for(int i=1;i<=m;i++) {
     77             scanf("%s",a[i]+1);
     78             for(int j=1;j<=n;j++) {
     79                 if(a[i][j]=='*') {
     80                     flag[i][j]=1;
     81                     num++;
     82                 }
     83             }
     84         }
     85         
     86         for(int i=1;i<=m;i++) {
     87             for(int j=1;j<=n;j++){
     88                 int p=(i-1)*n+j;
     89                 if((i+j)&1) {
     90                     if(flag[i][j]) b[k1++]=p;
     91                 } else {
     92                     if(flag[i][j]) c[k2++]=p;
     93                 }
     94             }
     95         } 
     96         
     97         for(int i=1;i<=m;i++) {
     98             for(int j=1;j<=n;j++) {
     99                 if(flag[i][j]) {
    100                     for(int k=0;k<4;k++) {
    101                         int nx=i+dx[k];
    102                         int ny=j+dy[k];
    103                         if(flag[nx][ny]) {
    104                             u=(i-1)*n+j;
    105                             v=(nx-1)*n+ny;
    106                             g[u][v]=1;
    107                         }
    108                     }
    109                 }
    110             }
    111         }
    112         
    113         int ans=hungary();
    114         printf("%d
    ",ans+num-2*ans);
    115         
    116         
    117     }
    118    
    119     
    120     
    121     return 0;
    122 }
  • 相关阅读:
    Git仓库操作笔记[Git repositories]
    supervisor 使用
    python动态加载(二)——动态加载类
    python动态加载(一)——加载方法
    python连接hdfs常用操作
    python对文件进行并行计算初探
    python加载包顺序和PYTHONPATH
    python实现读取数据库的断点续传
    python实现读取文件的断点续传
    python启动一个新进程
  • 原文地址:https://www.cnblogs.com/sxiszero/p/4383128.html
Copyright © 2020-2023  润新知