zoukankan      html  css  js  c++  java
  • HDU2236

    分析

    题干很简单,每行每列只能选一个,所以想到了状压DP???然后发现压不下来。。。
    于是又想到之前的一道将行和列连边的二分图的题,发现这个也可以。
    然后就只剩下了怎么求最小值,因为(n)的范围较小,所以可以尝试去把所有可能的答案枚举一下,直接枚举显然不可,所以要用到二分答案。
    所以就是先求出最大的答案,然后开始逐步缩小,遇到合法的就更新,最后输出。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=1e2+10;
    int g[N][N],n;
    int match[N],vis[N];
    bool dfs(int x,int l,int r){
        for(int i=1;i<=n;i++){
            if(vis[i]||g[x][i]>r||g[x][i]<l)continue;
            vis[i]=1314;
            if(match[i]==-1||dfs(match[i],l,r)){
                match[i]=x;
                return 1;
            }
        }
        return 0;
    }
    bool check(int l,int r){
        memset(match,-1,sizeof(match));
        for(int i=1;i<=n;i++){
            memset(vis,0,sizeof(vis));
            if(!dfs(i,l,r))return 0;
        }
        return 1;
    }
    int main(){
        int T;
        scanf("%d",&T);
        while(T--){
            int minn=0x3f3f3f3f;
            int maxx=0;
            scanf("%d",&n);
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++){
                    scanf("%d",&g[i][j]);
                    maxx=max(g[i][j],maxx);
                    minn=min(g[i][j],minn);
                }
            int l=0,r=maxx-minn;
            int ans=r;
            while(l<=r){
                int mid=l+r>>1;
                bool is=0;
                for(int i=minn;i+mid<=maxx;i++)
                    if(check(i,i+mid)){
                        is=1;break;
                    }
                if(is){
                    ans=mid;
                    r=mid-1;
                }else l=mid+1;
            }
            printf("%d
    ",ans);
        }
    }
    
  • 相关阅读:
    hadoop安装前的准备
    记录一次Qt5程序无法运行的解决过程
    C#里的Thread.Join与Control.Invoke死锁情况
    qbxt7月笔记
    zhxのDP讲
    有n*m的方格图
    最长上升子序列相关问题笔记
    qbxt游记(清北澡堂划水记
    DAZの七下道法(持续更新
    模板
  • 原文地址:https://www.cnblogs.com/anyixing-fly/p/12872927.html
Copyright © 2011-2022 走看看