CF538H Summer Dichotomy 题解
题意
- 有 名学生,你要从中选出至少 人,并将选出的人分成两组,可以有某一组是空的。
- 有 名老师,每名老师要被分配到两个小组之一,对于第 名老师,要求所在的小组中的学生人数 。
- 此外,有 对老师不能在同一个小组中。
- 你需要判断能否满足所有要求,如果可以,请给出一种方案。
- ,。
题解
先不考虑 的限制,可以证明 , 是最优的。
证明如下:
将所有 当作一条数轴上的线段,那么有三种情况:
- 有三条线段两两不交,则无解。
- 所有线段两两有交,即有 ,则在这种情况下,每个老师都可以随意的选择小组。
- ,在这种情况下,显然 不能更大,而更小则不优, 同理。
因此 , 一定是最优的。
如果考虑 的限制呢?可以发现,若 ,则无论哪种情况下,只增大 是最优的;若 ,则无论哪种情况下,只减小 的最优的。
因此我们可以直接求出最优的 ,最后做一次二分图染色即可。
时间复杂度 。
代码
#define Fail return prints("IMPOSSIBLE"), 0
const int N = 1e5 + 7;
int t, T, n, m, l[N], r[N], n1 = 1e9 + 1, n2 = -1, c[N];
vi e[N];
inline bool pd(int x, int i) {
return l[i] <= x && x <= r[i];
}
bool dfs(int x) {
for (auto y : e[x])
if (!c[y]) {
c[y] = 3 - c[x];
if (!dfs(y)) return 0;
} else if (c[x] == c[y]) return 0;
return 1;
}
int main() {
rd(t), rd(T), rd(n), rd(m);
for (int i = 1; i <= n; i++)
rd(l[i]), rd(r[i]), n1 = min(n1, r[i]), n2 = max(n2, l[i]);
if (n1 + n2 < t) n2 = t - n1;
if (n1 + n2 > T) n1 = T - n2;
if (n1 < 0 || n2 < 0) Fail;
for (int i = 1; i <= n; i++) {
bool o1 = pd(n1, i), o2 = pd(n2, i);
if (!o1 && !o2) Fail;
if (o1 && !o2) c[i] = 1;
if (!o1 && o2) c[i] = 2;
}
for (int i = 1, x, y; i <= m; i++)
rd(x), rd(y), e[x].pb(y), e[y].pb(x);
for (int i = 1; i <= n; i++) if (c[i] && !dfs(i)) Fail;
for (int i = 1; i <= n; i++)
if (!c[i]) {
c[i] = 1;
if (!dfs(i)) Fail;
}
string ans = "";
for (int i = 1; i <= n; i++) ans += c[i] + '0';
prints("POSSIBLE"), print(n1, ' '), print(n2), prints(ans);
return 0;
}
评论
暂无已公开评论。