[luogu5361]热闹的聚会与尴尬的聚会
由于两者是独立的,我们希望两者的$p$和$q$都最大
考虑最大的$p$,先全部邀请,此时要增大$p$显然必须要删去当前度数最小的点,不断删除之后将每一次度数最小值对答案取max即可
对于$q$也即最大独立集,并没有很好的解法,但考虑不断加入一个节点$x$,并删去$x$以及与$x$相邻的节点,重复此过程直至原图为空即得到了一个独立集
每一次贪心选择度数最小的节点$x$,显然$x$的度数一定不超过$p$,换言之每一次至多删去$p+1$个节点,最终要删去所有节点,即有$\lceil\frac{n}{p+1}\rceil\le q$
接下来要证明$\lfloor\frac{n}{q+1}\rfloor\le p$,注意到$\lfloor\frac{n}{q+1}\rfloor\le \lceil\frac{n}{q}\rceil-1$,而根据$\lceil\frac{n}{p+1}\rceil\le q$有$\lceil\frac{n}{q}\rceil\le p+1$,即得证
(用了快读+快输还是TLE了一个点)

1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 100005
4 set<pair<int,int> >s;
5 vector<int>ans;
6 struct Edge{
7 int nex,to;
8 }edge[N<<1];
9 int E,t,n,m,x,y,a[11],head[N],r[N],rr[N],vis[N];
10 int read(){
11 int x=0;
12 char c=getchar();
13 while ((c<'0')||(c>'9'))c=getchar();
14 while ((c>='0')&&(c<='9')){
15 x=x*10+c-'0';
16 c=getchar();
17 }
18 return x;
19 }
20 void write(int x){
21 a[0]=0;
22 while (x){
23 a[++a[0]]=x%10;
24 x/=10;
25 }
26 for(int i=a[0];i;i--)putchar(a[i]+'0');
27 }
28 void add(int x,int y){
29 edge[E].nex=head[x];
30 edge[E].to=y;
31 head[x]=E++;
32 }
33 int main(){
34 t=read();
35 while (t--){
36 n=read(),m=read();
37 E=0;
38 memset(head,-1,sizeof(head));
39 memset(r,0,sizeof(r));
40 for(int i=1;i<=m;i++){
41 x=read(),y=read();
42 add(x,y);
43 add(y,x);
44 r[x]++,r[y]++;
45 }
46 memcpy(rr,r,sizeof(r));
47 s.clear();
48 memset(vis,0,sizeof(vis));
49 for(int i=1;i<=n;i++)s.insert(make_pair(r[i],i));
50 for(int i=1;i<=n;i++){
51 x=(*s.begin()).second;
52 s.erase(s.begin());
53 vis[x]=i;
54 for(int i=head[x];i!=-1;i=edge[i].nex)
55 if (!vis[edge[i].to]){
56 s.erase(make_pair(r[edge[i].to],edge[i].to));
57 s.insert(make_pair(--r[edge[i].to],edge[i].to));
58 }
59 }
60 for(int i=1;i<=n;i++)r[0]=max(r[0],r[i]);
61 for(int i=1;i<=n;i++)
62 if (r[0]==r[i])x=i;
63 ans.clear();
64 for(int i=1;i<=n;i++)
65 if (vis[i]>=vis[x])ans.push_back(i);
66 write(ans.size());
67 putchar(' ');
68 for(int i=0;i<ans.size();i++){
69 write(ans[i]);
70 putchar(' ');
71 }
72 putchar('\n');
73 memcpy(r,rr,sizeof(r));
74 s.clear();
75 ans.clear();
76 memset(vis,0,sizeof(vis));
77 for(int i=1;i<=n;i++)s.insert(make_pair(r[i],i));
78 while (!s.empty()){
79 x=(*s.begin()).second;
80 s.erase(s.begin());
81 vis[x]=1;
82 ans.push_back(x);
83 for(int i=head[x];i!=-1;i=edge[i].nex)
84 if (!vis[edge[i].to]){
85 vis[edge[i].to]=1;
86 s.erase(make_pair(r[edge[i].to],edge[i].to));
87 for(int j=head[edge[i].to];j!=-1;j=edge[j].nex)
88 if (!vis[edge[j].to]){
89 s.erase(make_pair(r[edge[j].to],edge[j].to));
90 s.insert(make_pair(--r[edge[j].to],edge[j].to));
91 }
92 }
93 }
94 write(ans.size());
95 putchar(' ');
96 for(int i=0;i<ans.size();i++){
97 write(ans[i]);
98 putchar(' ');
99 }
100 putchar('\n');
101 }
102 }
[luogu5361]热闹的聚会与尴尬的聚会的更多相关文章
- vijos2054 SDOI2019 热闹的聚会与尴尬的聚会
题目链接 思路 首先观察题目最后的式子\(\lfloor \frac{n}{p + 1} \rfloor \le q\) 并且\(\lfloor \frac{n}{q+1} \rfloor \le p ...
- [SDOI2019]热闹又尴尬的聚会 构造,贪心
[SDOI2019]热闹又尴尬的聚会 链接 luogu loj 思路 第一问贪心?的从小到大删除入度最小的点,入度是动态的,打个标记. 当然不是最大独立集. 第二问第一问的顺序选独立集,不行就不要.选 ...
- SDOI2019热闹又尴尬的聚会
P5361 [SDOI2019]热闹又尴尬的聚会 出题人用脚造数据系列 只要将\(p\)最大的只求出来,\(q\)直接随便rand就能过 真的是 我们说说怎么求最大的\(p\),这个玩意具有很明显的单 ...
- 【题解】Luogu P5361 [SDOI2019]热闹又尴尬的聚会
原题传送门 构造题. 明显p,q都越大越好 我们考虑每次取出度最小的点,加到尴尬聚会的集合中(因为把与它相邻的点全删了,不珂能出现认识的情况),把它自己和与自己相连的点从图上删掉(边也删掉),记下这个 ...
- [SDOI2019] 热闹又尴尬的聚会
热闹度\(p\)子图中最小的度数,尴尬度\(q\)独立集大小,之间的约束 \[ \begin{aligned} \lfloor n/(p+1)\rfloor\le q &\rightarrow ...
- [洛谷P5361][SDOI2019]热闹又尴尬的聚会:构造题
分析 构造方法 (截图自UOJ群) 可以使用std::set维护这个过程,不过据说可以做到\(O(n+m)\).. 正确性证明 题目中的要求等价于\((p+1)(q+1) > n\) 设每次找出 ...
- [SDOI2019]热闹又尴尬的聚会(图论+set+构造)
据说原数据可以让复杂度不满的暴力O(Tn^2)过掉……O(Tn^2)方法类似于codeforces一场div2的E题 有一种比较好的方法:每次找出原图G中度最小的点加入q,然后将相邻的点加入新图G'. ...
- SDOI2019 Round2
这鬼家伙已经咕了好久了-- SDOIR2的题目挺好玩的- 快速查询(???) 不难发现所有的操作都可以通过区间打Tag实现 那么可以维护两个标记\(a,b\)表示序列中的数为\(x\)时实际表示的值是 ...
- Solution Set - 《赏竹而格之》
1.「GXOI / GZOI 2019」「洛谷 P5304」旅行者 Link & Submission. 经典二进制分组,没啥好说的. 2. 「SDOI 2019」「洛谷 P5361」 ...
随机推荐
- Go语言核心36讲(Go语言基础知识三)--学习笔记
03 | 库源码文件 在我的定义中,库源码文件是不能被直接运行的源码文件,它仅用于存放程序实体,这些程序实体可以被其他代码使用(只要遵从 Go 语言规范的话). 这里的"其他代码" ...
- SQL 居然还能在 Apache ShardingSphere 上实现这些功能?
在去年 10 月 5.0.0-alpha 版本发布之后,Apache ShardingSphere 经历了长达 8 个多月的持续开发与优化,终于在 6 月 25 日正式迎来了 5.0.0-beta 版 ...
- LOJ6356 四色灯(容斥+dp
纪念第一次所有的解析全写在代码里面 QWQ 这里就简单说几句了 首先一个灯有贡献,当且仅当他被按了\(4k\)次. 那么我们定义\(f(S)\)表示\([1,n]\)中有多少个数\(x\)是集合\(S ...
- python中dump与dumps实现序列化
前言 使用中如果我们想把python可识别对象的dict类型的数据通过str类型写入文件或者存入变量中就需要用到dump与dumps 详解 dump 1.新建个dict文件,然后将dict文件存入一个 ...
- 【UE4 C++】UKismetMathLibrary 源代码
// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreMinimal.h" # ...
- CentOS 文件管理
目录 目录管理 目录结构 切换目录 查看目录 创建目录 复制目录 剪切目录 删除目录 文件管理 查看文件 创建文件 复制文件 剪切文件 删除文件 创建链接 目录管理 目录也是一种文件. 蓝色目录,绿色 ...
- UltraSoft - Beta - 设计与计划
在DDL Killer的Alpha发布版本一周后,我们积累了一定的用户数量和用户反馈,同时也着手准备Beta阶段的继续开发,在正式开始迭代前,先对我们的Beta阶段的需求做一个统计和预估,一是保证工作 ...
- n阶行列式计算
1.化为上下三角 该类型的矩阵.行列式在之前写过(https://www.cnblogs.com/wangzheming35/p/12906624.html),也建议记住这个行列式的结论. 当然不仅仅 ...
- linux命令中find, which、whereis、locate,有什么区别?
whatis 用于查询一个命令执行什么功能,并将查询结果打印到终端上 which 查看可执行文件的位置 whereis 查看文件的位置 man Linux提供了丰富的帮助手册,当你需要查看某个命令的参 ...
- populating-next-right-pointers-in-each-node leetcode C++
Given a binary tree struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *nex ...