CF538H Summer Dichotomy
时间:2021-09-03
本文章向大家介绍CF538H Summer Dichotomy,主要包括CF538H Summer Dichotomy使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
一、题目
二、解法
\(\tt 2sat\) 的做法就不讲了,线段树优化建图要写麻
从另一个角度切入,我们可以先枚举每个小组中的学生人数,可以知道老师是否能分配到这个小组中,然后根据 \(m\) 个限制来对老师二分图染色即可。
瓶颈在于枚举学生人数,先不考虑总人数的限制,发现最优的取值是 \(n_1=\min\{r_i\},n_2=\max\{l_i\}\)
- 如果 \(n_1\geq n_2\),那么所有区间两两相交,这两个端点值最优。
- 如果 \(n_1<n_2\),那么增大 \(n_1\) 会让某个老师无法选组,减少 \(n_2\) 也会让某个老师无法选组,而减少 \(n_1\) 只会让 \(1\) 组的覆盖范围更少,增大 \(n_2\) 同理,所以它们是最优的。
如果 \(n_1+n_2\) 不符合总人数的限制怎么办?综合上面的讨论我们可以发现如果 \(n_1+n_2<t\) 那么我们增大 \(n_2\),如果 \(n_1+n_2>t\) 那么我们减小 \(n_1\),这样调整也是最优的。
最后只需要验证这一组 \((n_1,n_2)\) 是否能跑出二分图匹配即可,时间复杂度 \(O(n)\)
三、总结
区间问题着重考虑端点,可以将需要枚举的东西用贪心来最优化。
#include <cstdio>
#include <vector>
#include <cstdlib>
using namespace std;
const int M = 100005;
int read()
{
int x=0,f=1;char c;
while((c=getchar())<'0' || c>'9') {if(c=='-') f=-1;}
while(c>='0' && c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
return x*f;
}
int n,m,a,b,n1,n2,l[M],r[M],c[M],vis[M];
vector<int> g[M];
void dfs(int u)
{
vis[u]=1;
for(auto v:g[u])
{
if(c[v]==c[u])
{
puts("IMPOSSIBLE");
exit(0);
}
c[v]=3-c[u];
if(!vis[v]) dfs(v);
}
}
signed main()
{
a=read();b=read();n=read();m=read();
n1=1e9;n2=0;
for(int i=1;i<=n;i++)
{
l[i]=read();r[i]=read();
n1=min(n1,r[i]);
n2=max(n2,l[i]);
}
if(n1+n2<a) n2=a-n1;
if(n1+n2>b) n1=b-n2;
if(n1<0 || n2<0)
{
puts("IMPOSSIBLE");
return 0;
}
for(int i=1;i<=n;i++)
{
int f1=l[i]<=n1 && n1<=r[i];
int f2=l[i]<=n2 && n2<=r[i];
if(!f1 && !f2)
{
puts("IMPOSSIBLE");
return 0;
}
if(!f1) c[i]=2;
if(!f2) c[i]=1;
}
for(int i=1;i<=m;i++)
{
int u=read(),v=read();
g[u].push_back(v);
g[v].push_back(u);
}
for(int i=1;i<=n;i++)
if(c[i] && !vis[i]) dfs(i);
for(int i=1;i<=n;i++)
if(!vis[i]) c[i]=1,dfs(i);
puts("POSSIBLE");
printf("%d %d\n",n1,n2);
for(int i=1;i<=n;i++)
printf("%d",c[i]);
}
原文地址:https://www.cnblogs.com/C202044zxy/p/15223042.html
- LDA(Linear Discriminant Analysis)算法介绍
- Express.js 4,Node.js,MongoDB REST API 简易教程
- 基于梯度下降算法求解线性回归
- 彩色图像高斯反向投影
- OpenCV中直方图反向投影算法详解与实现
- 基于一维级联快速膨胀与腐蚀算法
- mac下利用Breakpad的dump文件进行调试
- OpenCV3.2集成Android Studio2.2开发配置
- laravel中使用gulp打包发布前端部分
- Spring的编程式事务和声明式事务
- Java过滤器Filter的使用详解
- 基于积分图的二值图像膨胀算法实现
- Java监听器Listener的使用详解
- 图像各向异性滤波
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- C#知识点讲解之C#delegate、event、Action、EventHandler的使用和区别
- typescript高级用法之infer的理解与使用
- 基于业务场景下的图片/文件上传方案总结
- LeetCode96|二叉搜索树中的搜索
- LeetCode95|字符串中的第一个唯一字符
- LeetCode94|Pow(x,n)
- LeetCode93|数值的整数次方
- LeetCode92|排序数组
- 缓存 | 从本地缓存到分布式缓存, Guava, Caffeine, Memcached, Redis
- WebView三问—B站真题
- C++核心准则T.140:为所有可能重用的操作命名
- Service三问
- 事件分发机制三问
- C++核心准则T.141:如果你需要只在一个地方使用的简单的函数对象,使用无名的lambda表达式
- 基于DOM的XML文件解析类