• HDU 2236 无题II


    不知道为什么今天的题都要嘲讽我这个做不出“简单”游戏的蒟蒻

    题意:给你一个n*n的方阵,从中选出n个数,且每行每列最多选一个,求选出的数中最大值和最小值的差,并是这个差最小。

    思路:和上次的题读起来有些相似之处,但这道题并不需要KM算法,由于每行每列只能选一个数,我们直接跑匈牙利算法求出匹配即可,关于最小差的问题呢?我们可以每次枚举我们二分图匹配时边权的取值范围,只有边权在这个范围内时我们才考虑将两点进行匹配,那么我们的答案就是当区间最小且完成匹配时的区间长度,单是直接枚举区间长度会超时间,于是我们采用二分的方法进行优化。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<vector>
     5 const int N=250;
     6 const int Inf=0x3f3f3f3f;
     7 using namespace std;
     8 int n,match[N],p,l,r,mid,g[N][N],vis[N];
     9 int dfs(int x){
    10     for(int i=1;i<=n;++i){
    11         if(p<=g[x][i]&&g[x][i]<=p+mid&&!vis[i]){
    12             vis[i]=1;
    13             if(!match[i]||dfs(match[i])){
    14                 match[i]=x;
    15                 return 1;
    16             }
    17         }
    18     }
    19     return 0;
    20 }
    21 bool work(){
    22     int ans=0;
    23     memset(match,0,sizeof(match));
    24     for(int i=1;i<=n;++i){
    25         memset(vis,0,sizeof(vis));
    26         if(dfs(i)) ans++;
    27     }
    28     return ans==n?1:0;
    29 }
    30 int main(){
    31     int t,Max,Min;
    32     scanf("%d",&t);
    33     while(t--){
    34         Max=-Inf;
    35         Min=Inf;
    36         scanf("%d",&n);
    37         for(int i=1;i<=n;++i)
    38         for(int j=1;j<=n;++j){
    39             scanf("%d",&g[i][j]);
    40             Max=max(Max,g[i][j]);//用于求出最大区间长度 
    41             Min=min(Min,g[i][j]);
    42         }
    43         l=0;r=Max-Min;//r是最大区间长度 
    44         int ans=0;
    45         while(l<=r){//二份枚举 
    46             int cnt=0;
    47             mid=((l+r)>>1);
    48             for(p=Min;p+mid<=Max;++p){
    49                 if(work()){//当前情况成立 
    50                     cnt=1;
    51                     break;
    52                 }
    53             }
    54             if(cnt){//记录答案 
    55                 ans=mid;
    56                 r=mid-1;
    57             }
    58             else l=mid+1;
    59         }
    60         printf("%d
    ",ans);
    61     }
    62     return 0;
    63 }
    View Code
  • 相关阅读:
    POJ 1061
    LightOJ 1104
    扩展欧几里得算法
    2015 HUAS Summer Trainning #5 E
    2015 HUAS Summer Trainning #5 C
    2015 HUAS Summer Trainning #5 B
    2015 HUAS Summer Trainning #5 A
    2015 HUAS Summer Trainning #4 D
    2015 HUAS Summer Trainning #4 C
    2015 HUAS Summer Trainning #4 B
  • 原文地址:https://www.cnblogs.com/li-jia-hao/p/12888267.html
Copyright © 2020-2023  润新知