zoukankan      html  css  js  c++  java
  • hdu 2236(最大匹配+枚举上下界)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2236

    思路:

    引:为了保证每行每列只取一个元素,我们可以从二分图最大匹配的思想入手,把行和列分别看做二分图左右两部分,i-j的边权就是第i行第j列的元素的值。这样构图之后,求得的二分图最大匹配的4条边就是不在同行或同列的4个元素。

    有了这个思想时候,我们只需要再保证4个元素中最大值与最小值之差尽量小就可以了,于是我们可以二分枚举最大值与最小值之差,并枚举边权值的下界,如果枚举到某个边权值的下界时该图存在最大匹配,那么就更新max,否则就更新min。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 using namespace std;
     7 #define MAXN 111
     8 int map[MAXN][MAXN];
     9 int lx[MAXN],ly[MAXN];
    10 bool mark[MAXN];
    11 int vmax,vmin,MIN,mid,MAX,p,n;
    12 bool flag;
    13 
    14 bool dfs(int u){
    15    for(int i=1;i<=n;i++){
    16       if(map[u][i]>=p&&map[u][i]<=p+mid&&!mark[i]){
    17          mark[i]=true;
    18          if(ly[i]==-1||dfs(ly[i])){
    19             ly[i]=u;
    20             lx[u]=i;
    21             return true;
    22          }
    23       }
    24    }
    25    return false;
    26 }
    27 
    28 bool Hungry(){
    29    memset(lx,-1,sizeof(lx));
    30    memset(ly,-1,sizeof(ly));
    31    for(int i=1;i<=n;i++){
    32       memset(mark,false,sizeof(mark));
    33       if(!dfs(i))return false;
    34    }
    35    return true;
    36 }
    37 int main(){
    38    int _case;
    39    scanf("%d",&_case);
    40    while(_case--){
    41       scanf("%d",&n);
    42       vmax=-100,vmin=100;
    43       for(int i=1;i<=n;i++){
    44          for(int j=1;j<=n;j++){
    45             scanf("%d",&map[i][j]);
    46             if(map[i][j]<vmin)vmin=map[i][j];
    47             if(map[i][j]>vmax)vmax=map[i][j];
    48          }
    49       }
    50       MAX=vmax-vmin;
    51       MIN=0;
    52       while(true)
    53       {
    54          mid=(MIN+MAX)>>1;
    55          flag=false;
    56          for(p=vmin;p+mid<=vmax;p++){
    57             if(Hungry()){ flag=true;break; }
    58          }
    59          if(flag)MAX=mid;
    60          if(MIN==mid)break;
    61          if(!flag)MIN=mid;
    62       }
    63       printf("%d\n",MAX);
    64    }
    65    return 0;
    66 }
    View Code
  • 相关阅读:
    JS中的正则表达式
    JavaScript之作用域
    JS中var、let、const 的区别
    Windows 下JAVA 1.8的安装以及环境变量的配置
    [js] 获取文本域光标位置,插入文本
    Elastic Search 权重及排序搜索结果中 _score 字段为 null
    goland配置
    kafka topic CONSUMER命令操作
    PHP 在windows上安装kafka扩展(phpstudy)
    jquery 遍历选中值 对象中嵌套数组 ajax保存
  • 原文地址:https://www.cnblogs.com/wally/p/3111433.html
Copyright © 2011-2022 走看看