fork download
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. typedef long long ll;
  6. typedef pair<int, int> ii;
  7.  
  8. const int INF = 1e9;
  9. const ll LINF = 1e18;
  10.  
  11. const int N = 2e2 + 5;
  12.  
  13. int n, k;
  14. int a[N][N];
  15.  
  16. int p[N], sz[N];
  17.  
  18. void initSet() {
  19. for (int u = 1; u <= n; u++) {
  20. p[u] = u;
  21. sz[u] = 1;
  22. }
  23. }
  24.  
  25. int findSet(int u) {
  26. if (p[u] == u) return u;
  27. return p[u] = findSet(p[u]);
  28. }
  29.  
  30. bool unionSet(int u, int v) {
  31. u = findSet(u);
  32. v = findSet(v);
  33. if (u == v) return false;
  34. if (sz[u] < sz[v]) swap(u, v);
  35. p[v] = u;
  36. sz[u] += sz[v];
  37. return true;
  38. }
  39.  
  40. // Có tồn tại cách chia n quân bài thành ít nhất k phần sao cho S >= mid
  41. // S = min(a(u, v)) với quân bài u, v ở hai phần khác nhau
  42. // Để S >= mid hay min(a(u, v)) >= mid
  43. // Thì a(u, v) >= mid (với mọi u, v ở hai phần khác nhau)
  44. bool check(int mid) {
  45. initSet();
  46.  
  47. // Những cặp (u, v) sao cho a[u][v] < mid phải ở chung một phần
  48. int cnt = n;
  49. for (int u = 1; u + 1 <= n; u++) {
  50. for (int v = u + 1; v <= n; v++) {
  51. if (a[u][v] < mid) cnt -= unionSet(u, v);
  52. }
  53. }
  54.  
  55. return (cnt >= k);
  56. }
  57.  
  58. int main() {
  59. ios::sync_with_stdio(false);
  60. cin.tie(nullptr);
  61. cin >> n >> k;
  62.  
  63. for (int u = 1; u <= n; u++) {
  64. for (int v = 1; v <= n; v++) cin >> a[u][v];
  65. }
  66.  
  67. int l = 0, r = 32767, ans = -1;
  68. while (l <= r) {
  69. int mid = (l + r) >> 1;
  70.  
  71. if (check(mid)) {
  72. ans = mid;
  73. l = mid + 1;
  74. }
  75. else {
  76. r = mid - 1;
  77. }
  78. }
  79.  
  80. cout << ans << '\n';
  81. }
Success #stdin #stdout 0s 5276KB
stdin
4 3
0 1 2 3
1 0 2 3
2 2 0 3
3 3 3 0
stdout
2