zoukankan      html  css  js  c++  java
  • HDU 2236:无题II(二分搜索+二分匹配)

    http://acm.hdu.edu.cn/showproblem.php?pid=2236

    题意:中文题意。

    思路:先找出最大和最小值,然后二分差值,对于每一个差值从下界开始枚举判断能不能二分匹配。

     1 #include <cstdio>
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <cstring>
     5 #include <string>
     6 #include <cmath>
     7 #include <queue>
     8 #include <vector>
     9 using namespace std;
    10 #define N 105
    11 #define INF 0x3f3f3f3f
    12 bool vis[N];
    13 int match[N];
    14 int mp[N][N];
    15 int n, mi, ma, run, mid;
    16 
    17 // 二分差值搜索枚举下界判断能不能成立
    18 
    19 bool dfs(int u)
    20 {
    21     for(int i = 1; i <= n; i++) {
    22         if(!vis[i]) {
    23             if(mp[u][i] < run || mp[u][i] > run + mid) continue; // 这个数不能小于下界也不能大于上界
    24             vis[i] = 1;
    25             if(match[i] == -1 || dfs(match[i])) {
    26                 match[i] = u;
    27                 return true;
    28             }
    29         }
    30     }
    31     return false;
    32 }
    33 
    34 bool solve() // 匈牙利算法
    35 {
    36     memset(match, -1, sizeof(match));
    37     for(int i = 1; i <= n; i++) {
    38         memset(vis, 0, sizeof(vis));
    39         if(!dfs(i)) return false;
    40     }
    41     return true;
    42 }
    43 
    44 int main()
    45 {
    46     int t;
    47     scanf("%d", &t);
    48     while(t--) {
    49         scanf("%d", &n);
    50         memset(mp, 0, sizeof(mp));
    51         mi = INF, ma = 0;
    52         for(int i = 1; i <= n; i++) {
    53             for(int j = 1; j <= n; j++) {
    54                 scanf("%d", &mp[i][j]);
    55                 if(mp[i][j] < mi) mi = mp[i][j];
    56                 if(mp[i][j] > ma) ma = mp[i][j];
    57             }
    58         }
    59         int l = 0, r = ma - mi, ans;
    60         while(l <= r) {
    61             mid = (l + r) / 2; // 二分差值
    62             bool f = 0;
    63             for(run = mi; run + mid <= ma; run++) // 从下界开始枚举
    64                 if(solve()) { r = mid - 1; break; }
    65             if(r != mid - 1) l = mid + 1;
    66 //            printf("%d, %d, %d
    ", l, r, mid);
    67         }
    68         printf("%d
    ", l);
    69     }
    70     return 0;
    71 }
    72 
    73 /*
    74 2
    75 4
    76 1 2 1 1
    77 2 2 2 2
    78 3 3 3 3
    79 4 4 4 4
    80 4
    81 1 1 1 1
    82 1 2 2 2
    83 3 1 3 3
    84 4 4 1 4
    85 */
  • 相关阅读:
    Servlet的生命周期及工作原理
    抓包---firebug
    firebug抓包
    token认证来龙去脉
    性能测试报告注意事项
    性能测试报告
    Error -26601解决办法
    lr新手误区
    css定位
    xpath定位
  • 原文地址:https://www.cnblogs.com/fightfordream/p/6038413.html
Copyright © 2011-2022 走看看