[CF538H]Summer Dichotomy

[CF538H]Summer Dichotomy

题目大意:

​ 将若干个学生分为两个班级\(S_1,S_2\),每个班的学生数分别为\(n_1,n_2\)(甚至可以没有学生,也可以没有老师)。给出限制\(t_{\min},t_{\max}\),要求\(t_{\min}\le n_1+n_2\le t_{\max}\)。有\(n(n\le10^5)\)个老师,每个老师希望他所任教的班级人数在\([l_i,r_i]\)范围内。有\(m(m\le10^5)\)对老师之间有一些私人恩怨,不能分在一个班级。问是否存在合法的分班方案。如果有,求出其中的任意一种,输出每个班的总人数以及各个老师所任教的班级。

思路:

​ 对于所有\([l_i,r_i]\)的限制,我们不妨假设\(n_1=\min\{r_i\},n_2=\max\{l_i\}\),显然这是比较松的约束。再考虑\(t_{\min},t_{\max}\)的限制,确定可行的一组\(n_1,n_2\)。考虑二分图染色构造老师分配的方案。对于只能分到\(S_1\)或只能分到\(S_2\)的老师DFS遍历染色,若更新到的结点与已染色结点矛盾,说明根本不是二分图,不存在合法的方案。对于两个都不可以分进去的,说明也不存在合法方案。最后再对于\(S_1\)\(S_2\)都可以的进行染色。

源代码:

#include<cstdio>
#include<cctype>
#include<vector>
#include<climits>
inline int getint() {
	register char ch;
	while(!isdigit(ch=getchar()));
	register int x=ch^'0';
	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
	return x;
}
constexpr int N=1e5;
int l[N],r[N],ans[N];
std::vector<int> e[N];
inline void add_edge(const int &u,const int &v) {
	e[u].push_back(v);
	e[v].push_back(u);
}
void dfs(const int &x,const int &c) {
	if(ans[x]) {
		if(ans[x]!=c) throw(0);
		return;
	}
	ans[x]=c;
	for(auto &y:e[x]) {
		dfs(y,3-c);
	}
}
int main() {
	const int t_min=getint(),t_max=getint();
	const int n=getint(),m=getint();
	int n1=INT_MAX,n2=INT_MIN;
	for(register int i=0;i<n;i++) {
		n2=std::max(n2,l[i]=getint());
		n1=std::min(n1,r[i]=getint());
	}
	if(n1+n2<t_min) n2=t_min-n1;
	else if(n1+n2>t_max) n1=t_max-n2;
	if(n1<0||n2<0) {
		puts("IMPOSSIBLE");
		return 0;
	}
	for(register int i=0;i<m;i++) {
		add_edge(getint()-1,getint()-1);
	}
	for(register int i=0;i<n;i++) {
		try {
			if(!(l[i]<=n1&&n1<=r[i])&&!(l[i]<=n2&&n2<=r[i])) throw(0);
			if((l[i]<=n1&&n1<=r[i])&&!(l[i]<=n2&&n2<=r[i])) dfs(i,1);
			if((l[i]<=n2&&n2<=r[i])&&!(l[i]<=n1&&n1<=r[i])) dfs(i,2);
		} catch(...) {
			puts("IMPOSSIBLE");
			return 0;
		}
	}
	for(register int i=0;i<n;i++) {
		try {
			if(!ans[i]) dfs(i,1);
		} catch(...) {
			puts("IMPOSSIBLE");
			return 0;
		}
	}
	puts("POSSIBLE");
	printf("%d %d\n",n1,n2);
	for(register int i=0;i<n;i++) {
		printf("%d",ans[i]);
	}
	return 0;
}
posted @ 2018-05-24 18:26  skylee03  阅读(474)  评论(0编辑  收藏  举报