|
| 1 | +/** |
| 2 | + * LeetCode Biweekly Contest Problem - LC 3710 |
| 3 | + * |
| 4 | + * Problem Statement (inferred from code): |
| 5 | + * Given a set of points, partition them into at most 2 groups such that |
| 6 | + * within each group, any pair of points has a Manhattan distance ≥ D, |
| 7 | + * and both groups are bipartite (no odd-length cycles). |
| 8 | + * |
| 9 | + * Goal: Find the **maximum possible D** such that the above condition holds. |
| 10 | + * |
| 11 | + * Approach: |
| 12 | + * - Binary search on distance D. |
| 13 | + * - For each candidate D, create an undirected graph where an edge exists |
| 14 | + * between two points if their distance is **less than D**. |
| 15 | + * - If this graph is **bipartite**, it's a valid partition for D. |
| 16 | + * - Return the largest D that satisfies this. |
| 17 | + */ |
| 18 | + |
| 19 | + typedef long long ll; |
| 20 | + |
| 21 | +class dsu { |
| 22 | +public: |
| 23 | + ll n; |
| 24 | + vector<ll> par; |
| 25 | + vector<vector<ll>> gd; |
| 26 | + |
| 27 | + // Constructor to initialize DSU with N nodes |
| 28 | + dsu(ll N) { |
| 29 | + n = N; |
| 30 | + par.resize(N, 0); |
| 31 | + gd.resize(N); |
| 32 | + for (ll i = 0; i < n; i++) { |
| 33 | + par[i] = i; // Each node is its own parent |
| 34 | + gd[i].push_back(i); // Each group starts with one element |
| 35 | + } |
| 36 | + } |
| 37 | + |
| 38 | + // Find with path compression |
| 39 | + ll find(ll u) { |
| 40 | + if (par[u] != u) |
| 41 | + return par[u] = find(par[u]); |
| 42 | + return u; |
| 43 | + } |
| 44 | + |
| 45 | + // Union two sets |
| 46 | + void comb(ll u, ll v) { |
| 47 | + ll ru = find(u), rv = find(v); |
| 48 | + if (ru != rv) { |
| 49 | + par[rv] = ru; |
| 50 | + gd[ru].push_back(rv); // Merge group |
| 51 | + } |
| 52 | + } |
| 53 | + |
| 54 | + // Check if number of disjoint sets is at most 2 |
| 55 | + bool f() { |
| 56 | + vector<ll> vis(n, 0); |
| 57 | + ll ct = 0; |
| 58 | + for (ll i = 0; i < n; i++) { |
| 59 | + ll ri = find(i); |
| 60 | + if (vis[ri]) continue; |
| 61 | + vis[ri] = 1; |
| 62 | + ct++; |
| 63 | + } |
| 64 | + return ct <= 2; |
| 65 | + } |
| 66 | +}; |
| 67 | +#include<bits/stdc++.h> |
| 68 | +using namespace std; |
| 69 | +class Solution { |
| 70 | +public: |
| 71 | + // Check if the undirected graph is bipartite |
| 72 | + bool isBipartite(const std::vector<std::vector<ll>>& adj, ll N) { |
| 73 | + std::vector<int> c(N, 0); // Color array: 0 = unvisited, 1 or 2 = color |
| 74 | + |
| 75 | + for (ll i = 0; i < N; ++i) { |
| 76 | + if (c[i] != 0) continue; |
| 77 | + |
| 78 | + std::queue<ll> q; |
| 79 | + q.push(i); |
| 80 | + c[i] = 1; // Start coloring with 1 |
| 81 | + |
| 82 | + while (!q.empty()) { |
| 83 | + ll u = q.front(); |
| 84 | + q.pop(); |
| 85 | + |
| 86 | + for (ll v : adj[u]) { |
| 87 | + if (c[v] == 0) { |
| 88 | + c[v] = 3 - c[u]; // Alternate color |
| 89 | + q.push(v); |
| 90 | + } else if (c[v] == c[u]) { |
| 91 | + return false; // Same color on both ends — not bipartite |
| 92 | + } |
| 93 | + } |
| 94 | + } |
| 95 | + } |
| 96 | + return true; |
| 97 | + } |
| 98 | + |
| 99 | + // Check if it's possible to partition at distance ≥ dist |
| 100 | + bool ispos(vector<vector<ll>>& adj, ll& dist, ll& N) { |
| 101 | + vector<vector<ll>> edges(N); |
| 102 | + |
| 103 | + // Build graph: edge if distance < dist |
| 104 | + for (ll i = 0; i < N; i++) { |
| 105 | + for (int j = i + 1; j < N; j++) { |
| 106 | + if (adj[j][i] < dist) { |
| 107 | + edges[i].push_back(j); |
| 108 | + edges[j].push_back(i); |
| 109 | + } |
| 110 | + } |
| 111 | + } |
| 112 | + |
| 113 | + // Check if the graph is bipartite |
| 114 | + return isBipartite(edges, N); |
| 115 | + } |
| 116 | + |
| 117 | + // Manhattan distance between two points |
| 118 | + ll g(vector<int>& p1, vector<int>& p2) { |
| 119 | + return abs(p1[0] - p2[0]) + abs(p1[1] - p2[1]); |
| 120 | + } |
| 121 | + |
| 122 | + int maxPartitionFactor(vector<vector<int>>& pts) { |
| 123 | + ll n = pts.size(); |
| 124 | + if (n <= 2) return 0ll; |
| 125 | + |
| 126 | + vector<vector<ll>> adj(n, vector<ll>(n, LLONG_MAX)); |
| 127 | + ll MX = 1; |
| 128 | + |
| 129 | + // Precompute all pairwise Manhattan distances |
| 130 | + for (int i = 0; i < n; i++) { |
| 131 | + for (int j = i + 1; j < n; j++) { |
| 132 | + ll MD = g(pts[i], pts[j]); |
| 133 | + adj[i][j] = adj[j][i] = MD; |
| 134 | + MX = max(MD, MX); // Track max distance |
| 135 | + } |
| 136 | + } |
| 137 | + |
| 138 | + // Binary search over possible D |
| 139 | + ll lo = 0, hi = MX; |
| 140 | + while (lo < hi) { |
| 141 | + ll mid = (lo + hi + 1) / 2; |
| 142 | + if (ispos(adj, mid, n)) { |
| 143 | + lo = mid; // Valid partition, try higher |
| 144 | + } else { |
| 145 | + hi = mid - 1; // Invalid, reduce D |
| 146 | + } |
| 147 | + } |
| 148 | + |
| 149 | + return hi; |
| 150 | + } |
| 151 | +}; |
0 commit comments