zoukankan      html  css  js  c++  java
  • 无题II HDU

    此题参考了 西瓜不懂柠檬的酸  dalao的博客 点击打开链接
    /**
    中文题,自己好好理解一下题意。
    想到基本算法很简单,就是一个匈牙利算法,但是,难点在于,如何使得最大值,最小值的差最小
    要求最大值与最小值的差值最小,是通过枚举边的下限和上限来完成
    只需要用二分找一个区间,然后不断枚举这个区间是否可以达到最大匹配,一直二分到答案为止。*/
    
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int Maxx=105;
    const int inf=0x3f3f3f3f;
    int link[Maxx][Maxx],match[Maxx],vis[Maxx];
    int MaxR,MinL,Max,Min,R,L,n;///MaxR,MinL记录最大最小值,Max,Min记录区间的上下限,L,R记录二分查找差值的上下限//
    bool dfs(int x)
    {
        for(int i=1;i<=n;i++){
            if(!vis[i]&&link[x][i]>=Min&&link[x][i]<=Max){
                vis[i]=1;
                if(!match[i]||dfs(match[i])){
                    match[i]=x;
                    return 1;
                }
            }
        }
        return 0;
    }
    bool hungary()///匈牙利算法
    {
        memset(match,0,sizeof match);
        for(int i=1;i<=n;i++){
            memset(vis,0,sizeof vis);
            if(!dfs(i))
                return 0;
        }
        return 1;
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--){
            memset(link,0,sizeof link);
            MaxR=-1,MinL=inf;
            scanf("%d",&n);
            for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++){
                scanf("%d",&link[i][j]);
                MaxR=max(MaxR,link[i][j]);
                MinL=min(MinL,link[i][j]);
            }
            L=0;
            R=MaxR-MinL;///差值的的上下限
            int ans=0;
            while(L<=R){
                int flag=0;
                int mid=(L+R)/2;
                for(int i=MinL;i+mid<=MaxR;i++){
                    Min=i;///如果差值为mid,那么,查找一个区间是,这个区间的最小值为i,最大值为i+mid
                    Max=i+mid;
                    if(hungary()){///如果在值在区间i,i+mid之间,并且可以完成匹配,那么说明可能存在一个差值比mid还要小,所以令上界减一,否则令下界加一
                        flag=1;
                        break;
                    }
                }
                if(flag){///上界减一,使得差值变小
                    ans=mid;
                    R=mid-1;
                }
                else///下界加一,使得差值变大
                    L=mid+1;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    

  • 相关阅读:
    示例vue 的keep-alive缓存功能的实现
    解析Vue.js中的computed工作原理
    CentOS7.2 问题收集 查看文件大小 查看端口
    Docker 配置阿里云镜像加速器
    CentOS7.2中systemctl的使用
    CentOS7.2 安装Docker
    Java 多线程中的任务分解机制-ForkJoinPool,以及CompletableFuture
    IntelliJ IDEA 在运行web项目时部署的位置
    Mysql相关问题收集
    Java命令使用 jmap,jps,jstack,jstat,jhat,jinfo
  • 原文地址:https://www.cnblogs.com/Levi-0514/p/9042491.html
Copyright © 2011-2022 走看看