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 */
原文地址:https://www.cnblogs.com/fightfordream/p/6038413.html