• HDU 4185 Oil Skimming 【最大匹配】


    <题目链接>

    题目大意:

    给你一张图,图中有 '*' , '.' 两点,现在每次覆盖相邻的两个 '#' ,问最多能够覆盖几次。

    解题分析:

    无向图二分匹配的模板题,每个'#'点与周围四个方向的'#'建立匹配关系,然后用匈牙利跑一遍,因为匹配的两点各会进行相互匹配一次,所以最大匹配数为ans/2。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 using namespace std;
     5 
     6 const int N=600+10;   //本题数据中'#'数量较少,开到600都能AC 
     7 char mpa[605][605];
     8 int n,vN,vM;
     9 int g[N][N],cnt[605][605],vis[N],match[N];
    10 bool dfs(int x){
    11     for(int i=1;i<=vM;i++){
    12         if(g[x][i]&&!vis[i]){
    13             vis[i]=1;
    14             if(match[i]==-1||dfs(match[i])){
    15                 match[i]=x;
    16                 return true;
    17             }
    18         }
    19     }
    20     return false;
    21 }
    22 int Hungary(){
    23     int ans=0;
    24     memset(match,-1,sizeof(match));
    25     for(int i=1;i<=vN;i++){
    26         memset(vis,0,sizeof(vis));
    27         if(dfs(i))ans++;
    28     }
    29     return ans;
    30 }
    31 int main(){
    32     int T;scanf("%d",&T);
    33     int ncase=0;
    34     while(T--){
    35         scanf("%d",&n);
    36         int pos=0;
    37         for(int i=1;i<=n;i++){
    38             scanf("%s",mpa[i]+1);
    39             for(int j=1;j<=n;j++)
    40                 if(mpa[i][j]=='#')cnt[i][j]=++pos;     //给所有的'#'分配编号
    41         }
    42         memset(g,0,sizeof(g));
    43         //将该点与其周围四个方向的'#'都建立匹配关系
    44         for(int i=1;i<=n;i++){
    45             for(int j=1;j<=n;j++){
    46                 if(mpa[i][j]!='#')continue;
    47                 if(i-1>=1&&mpa[i-1][j]=='#')g[cnt[i][j]][cnt[i-1][j]]=1;
    48                 if(j-1>=1&&mpa[i][j-1]=='#')g[cnt[i][j]][cnt[i][j-1]]=1;
    49                 if(i+1<=n&&mpa[i+1][j]=='#')g[cnt[i][j]][cnt[i+1][j]]=1;
    50                 if(j+1<=n&&mpa[i][j+1]=='#')g[cnt[i][j]][cnt[i][j+1]]=1;
    51             }
    52         }
    53         vN=vM=pos;
    54         int ans=Hungary();   //求出最大匹配数
    55         printf("Case %d: %d
    ",++ncase,ans/2);    //因为匹配的两点会相互各进行一次匹配,所以这里要除以2
    56     }
    57     return 0;
    58 }

    2018-11-14

  • 相关阅读:
    js中(function(){…})()立即执行函数写法理解
    JS 立即执行的函数表达式(function)写法
    javascript中call,apply,bind的用法对比分析
    C++成员函数指针的应用
    typeid详解
    dynamic_cast
    C++标准转换运算符dynamic_cast
    继承的构造函数
    考虑写一个不抛出异常的swap函数
    布隆过滤器(转)
  • 原文地址:https://www.cnblogs.com/00isok/p/9959562.html
Copyright © 2020-2023  润新知