上海高校金马五校赛 J - 小Y写文章
题目大意: 给你n个数字, 定义不连贯值为, max(abs(a[ i ] - b[ i ])) ,现在让你把m个新的数字插入n + 1 个空位中,使得不连贯值最小。
思路:二分不连贯值, 每次进行二分图匹配, 注意进行二分图匹配的时候需要加入虚拟的点,因为这n + 1个空位中有些点是必须加数字的。
1 #include<bits/stdc++.h> 2 #define LL long long 3 #define fi first 4 #define se second 5 #define mk make_pair 6 #define pii pair<int, int> 7 using namespace std; 8 9 const int N=400+7; 10 const int M=100+7; 11 const int inf=0x3f3f3f3f; 12 const LL INF=0x3f3f3f3f3f3f3f3f; 13 const int mod=1e9 + 9; 14 15 int n, m, a[N], b[N],cx[N], cy[N], vis[N]; 16 vector<int> edge[N]; 17 18 bool path(int u) 19 { 20 for(int v : edge[u]) 21 { 22 if(!vis[v]) 23 { 24 vis[v] = 1; 25 if(cy[v] == -1 || path(cy[v])) 26 { 27 cx[u] = v; 28 cy[v] = u; 29 return true; 30 } 31 } 32 } 33 return false; 34 } 35 36 bool maxmatch() 37 { 38 int res=0; 39 memset(cx, -1, sizeof(cx)); 40 memset(cy, -1, sizeof(cy)); 41 for(int i = 1; i <= 2 * n + 2; i++) 42 { 43 if(cx[i] == -1) 44 { 45 memset(vis, 0, sizeof(vis)); 46 if(path(i)) continue; 47 else return false; 48 } 49 } 50 return true; 51 } 52 53 bool check(int x) { 54 for(int i = 1; i <= 2 * n + 2; i++) 55 edge[i].clear(); 56 for(int i = 1; i <= n + 1; i++) { 57 if(i == 1) { 58 for(int j = 1; j <= m; j++) { 59 if(abs(b[j] - a[1]) <= x) { 60 edge[i].push_back(n + 1 + j); 61 edge[n + 1 + j].push_back(i); 62 } 63 } 64 for(int j = m + 1; j <= n + 1; j++) { 65 edge[i].push_back(n + 1 + j); 66 edge[n + 1 + j].push_back(i); 67 } 68 } else if(i == n + 1) { 69 for(int j = 1; j <= m; j++) { 70 if(abs(b[j] - a[n]) <= x) { 71 edge[i].push_back(n + 1 + j); 72 edge[n + 1 + j].push_back(i); 73 } 74 } 75 for(int j = m + 1; j <= n + 1; j++) { 76 edge[i].push_back(n + 1 + j); 77 edge[n + 1 + j].push_back(i); 78 } 79 } else { 80 for(int j = 1; j <= m; j++) { 81 if((abs(b[j] - a[i]) <= x) && abs(b[j] - a[i - 1]) <= x) { 82 edge[i].push_back(n + 1 + j); 83 edge[n + 1 + j].push_back(i); 84 } 85 } 86 if(abs(a[i] - a[i - 1]) <= x) { 87 for(int j = m + 1; j <= n + 1; j++) { 88 edge[i].push_back(n + 1 + j); 89 edge[n + 1 + j].push_back(i); 90 } 91 } 92 } 93 } 94 return maxmatch(); 95 } 96 int main() { 97 int T; scanf("%d", &T); 98 while(T--) { 99 scanf("%d%d", &n, &m); 100 for(int i = 1; i <= n; i++) 101 scanf("%d", &a[i]); 102 for(int i = 1; i <= m; i++) 103 scanf("%d", &b[i]); 104 105 int l = 0, r = 1e9, ans = -1; 106 107 while(l <= r) { 108 int mid = (l + r) >> 1; 109 if(check(mid)) { 110 ans = mid; 111 r = mid - 1; 112 } else { 113 l = mid + 1; 114 } 115 } 116 printf("%d\n", ans); 117 } 118 return 0; 119 } 120 /*************** 121 ****************/