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;
    }
    

  • 相关阅读:
    文件下载
    Regularexpressionvalidator控件常用正则表达式
    确认删除
    回发或回调参数无效。
    回车提交表单
    具有身份验证的web.config
    OleDbParameter参数的使用
    把CS文件编译成dll文件
    .Net简单三层
    ASP.NET 2.0中的页面输出缓存
  • 原文地址:https://www.cnblogs.com/Levi-0514/p/9042491.html
Copyright © 2011-2022 走看看