无题II(二分 + 匈牙利匹配)
Posted dzn2004
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无题II(二分 + 匈牙利匹配)相关的知识,希望对你有一定的参考价值。
Problem Description
这是一个简单的游戏,在一个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
——————————————————————————————————————————————————————————————————
首先,先明确,对于所取的每一个数,它的行和列一一对应,不会重复对应,于是将行数字和列数字看做A,B部,每个数字即连线,这是一个二分图
然后二分差值,从最小值一直枚举差值区间,看是不是能够找到完美匹配
——————————————————————————————————————————————————————————————————
代码:
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdlib> 5 #include<algorithm> 6 using namespace std; 7 const int INF = 0x3f3f3f3f; 8 const int Max = 105; 9 int maxn,maxm,down,mid; 10 int match[Max]; 11 int map[Max][Max]; 12 bool vis[Max]; 13 void getint(int & num){ 14 char c; int flg = 1; num = 0; 15 while((c = getchar()) < ‘0‘ || c > ‘9‘) if(c == ‘-‘) flg = -1; 16 while(c >= ‘0‘ && c <= ‘9‘){ num = num * 10 + c - 48; c = getchar();} 17 num *= flg; 18 } 19 int max(int a, int b){ return a < b ? b : a;} 20 int min(int a, int b){ return a < b ? a : b;} 21 bool HUN(int x){ 22 for(int i = 1; i <= maxn; ++ i) if(map[x][i] >= down && map[x][i] <= down + mid && ! vis[i]){ 23 vis[i] = 1; 24 if(! match[i] || HUN(match[i])){ 25 match[i] = x; 26 return 1; 27 } 28 } 29 return 0; 30 } 31 bool checkk(){ 32 memset(match, 0, sizeof(match)); 33 for(int i = 1; i <= maxn; ++ i){ 34 memset(vis, 0, sizeof(vis)); 35 if(! HUN(i)) return 0; 36 } 37 return 1; 38 } 39 int main(){ 40 //freopen("a.in","r",stdin); 41 int T;getint(T); 42 while(T --){ 43 getint(maxn); 44 int maxv = -INF, minv = INF; 45 for(int i = 1; i <= maxn; ++ i) 46 for(int j = 1; j <= maxn; ++ j){ 47 getint(map[i][j]); 48 maxv = max(maxv, map[i][j]); 49 minv = min(minv, map[i][j]); 50 } 51 int l = 0, r = maxv - minv, rt; 52 while(l <= r){ 53 mid = (l + r) >> 1; 54 bool flg = 0; 55 for(down = minv; down + mid <= maxv; ++ down) 56 if(checkk()){ 57 flg = 1; 58 break; 59 } 60 if(flg) rt = mid, r = mid - 1; 61 else l = mid + 1; 62 } 63 printf("%d ", rt); 64 } 65 return 0; 66 }
以上是关于无题II(二分 + 匈牙利匹配)的主要内容,如果未能解决你的问题,请参考以下文章