标签:
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2236
要求最大值与最小值的差值最小,是通过枚举边的下限和上限来完成
只需要用二分找一个区间,然后不断枚举这个区间是否可以达到最大匹配,一直二分到答案为止。
#include<stdio.h> #include<string.h> #include<math.h> #include<queue> #include<algorithm> using namespace std; #define N 110 #define INF 0xfffffff int maps[N][N], n, Min, Max, ans, used[N], vis[N]; bool Find(int u) { for(int i=1; i<=n; i++) { if(!vis[i] && maps[u][i]>=Min && maps[u][i]<=Max) { vis[i] = 1; if(!used[i] || Find(used[i])) { used[i] = u; return true; } } } return false; } bool xyl() { memset(used, 0, sizeof(used)); for(int i=1; i<=n; i++) { memset(vis, 0, sizeof(vis)); if(!Find(i)) return false; } return true; } int main() { int T, MinL, MaxR; scanf("%d", &T); while(T--) { scanf("%d", &n); MaxR = 0; MinL = INF; for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { scanf("%d", &maps[i][j]); MinL = min(maps[i][j], MinL); MaxR = max(maps[i][j], MaxR); } } int L = 0; int R = MaxR - MinL; ans = 0; while(L<=R) { int flag = 0; int i,Mid=(L+R)/2; for(i=MinL; i+Mid<=MaxR; i++)/// { Min = i; Max = i + Mid; if(xyl())///说明可能还有比mid还小的差; { flag = 1; break; } } if(flag) { ans=Mid; R=Mid-1; } else L=Mid+1; } printf("%d\n", ans); } return 0; }
标签:
原文地址:http://www.cnblogs.com/zhengguiping--9876/p/4731843.html