zoukankan      html  css  js  c++  java
  • 2M——二分图+二分答案

    题目

    这是一个简单的游戏,在一个(n*n)的矩阵中,找(n)个数使得这(n)个数都在不同的行和列里并且要求这(n)个数中的最大值和最小值的差值最小。

    Input

    输入一个整数(T)表示(T)组数据。
    对于每组数据第一行输入一个正整数(n(1<=n<=100))表示矩阵的大小。
    接着输入(n)行,每行(n)个数(x(0<=x<=100))

    Output

    对于每组数据输出一个数表示最小差值。

    Sample Input

    1
    4
    1 1 1 1
    2 2 2 2
    3 3 3 3
    4 4 4 4
    

    Sample Output

    3
    

    题解

    解题思路

    我们看题目,每行每列都找一个数,可以想到用二分图最大匹配
    然后就是枚举了,暴力的话一定是不行的
    我们就可以通过二分答案来进行枚举

    代码

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int N = 105, M = 0x7fffffff;
    int T, n, a[N][N], l, r, mid, ans, mi, ma, m[N], v[N];
    bool dfs(int x, int s, int d) {
        for(int i = 1; i <= n; i++) 
            if (!v[i] && s <= a[x][i] && s + d >= a[x][i]) {
                v[i] = 1;
                if (m[i] == -1 || dfs(m[i], s, d)) {
                    m[i] = x;
                    return 1;
                }
            }
        return 0;
    }
    bool judge(int d) {
        for(int s = mi; s + d <= ma; s++) {
            memset(m, -1, sizeof(m));
            int sum = 0;
            for(int i = 1; i <= n; i++) {
                memset(v, 0, sizeof(v));
                if (dfs(i, s, d)) sum++;
            }
            if (sum == n) return 1;
        }
        return 0;
    }
    int main() {
        scanf("%d", &T);
        while (T--) {
            scanf("%d", &n);
            mi = M; ma = -M;
            for(int i = 1; i <= n; i++)
                for(int j = 1; j <= n; j++) {
                    scanf("%d", &a[i][j]);
                    mi = min(mi, a[i][j]);
                    ma = max(ma, a[i][j]);
                }
            l = 0; r = ma - mi; ans = 0;
            while(l <= r) {
                mid = (l + r) >> 1;
                if (judge(mid)) ans = mid, r = mid - 1;
                else l = mid + 1;
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
    
  • 相关阅读:
    递归 深拷贝
    js 基础复习(0)
    js数组冒泡排序,快速排序的原理以及实现
    .sass 和 .scss 区别
    ionic2-从搭建环境说起
    Unity3d截图保存到Android相册的实现
    总是要总结一年的工作(写给自己和想要从技术创业开公司的朋友们)
    初入职场(插曲-如何更称职的工作)
    初入职场(插曲-你的成长代价)
    初入职场(面试)
  • 原文地址:https://www.cnblogs.com/shawk/p/12884642.html
Copyright © 2011-2022 走看看