不妨设$a\le b\le c$,那么相当于要找到两个大小至少为$a$和$b$的连通块(连通块可以通过删除度最小的点变小)
以一个点为根建出dfs树并对以下情况分类讨论:
1.存在一个节点满足$\max(\max_{son}(sz[son]),n-sz[k]+s)<a$(其中$sz[k]$表示k子树大小,$s$表示删除$k$后仍然与根联通的点个数),那么必然无解(两个连通块必然都需要经过$k$)
2.不存在,那么必然有解,且可以通过以下方法构造:
(1)找到任意一个满足$sz[k]\ge a$且$\max_{son}(sz[son])<a$的点$k$
(2)若$n-sz[k]+s\ge b$,将在$k$子树中且删去$k$后无法与根联通的$x$加入$S_{a}$,对于剩下的子树不断加入$S_{a}$直到$S_{a}$大小不小于$a$,然后剩下的点归入$S_{b}$
由于$\max_{son}(sz[son])<a$,因此$S_{a}$的大小最多为$2a$,那么$|S_{b}|=n-2a\ge n-a-c=b$
(3)若$n-sz[k]+s<b$,由于$b\le \lfloor \frac{n}{2}\rfloor$,因此$sz[k]>\lceil \frac{n}{2}\rceil+s>b$,同时$n-sz[k]+s\ge a$(否则无解),那么交换$a$和$b$后用同样的方法即可
(代码中有一些小问题,可以通过随机根解决QAQ)

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 100005
4 struct ji{
5 int nex,to;
6 }edge[N<<2];
7 pair<int,int>a[11];
8 int E,r,n,m,x,y,flag,head[N],sz[N],dfn[N],low[N],tot[N],ans[N];
9 void add(int x,int y){
10 edge[E].nex=head[x];
11 edge[E].to=y;
12 head[x]=E++;
13 }
14 void update(int k,int p){
15 if ((!a[p].first)||(ans[k]))return;
16 a[p].first--;
17 ans[k]=a[p].second;
18 for(int i=head[k];i!=-1;i=edge[i].nex)
19 if (edge[i].to)update(edge[i].to,p);
20 }
21 void dfs(int k,int fa){
22 int mx=0,s=0;
23 sz[k]=1;
24 dfn[k]=low[k]=++x;
25 for(int i=head[k];i!=-1;i=edge[i].nex)
26 if (!sz[edge[i].to]){
27 dfs(edge[i].to,k);
28 if (flag)return;
29 sz[k]+=sz[edge[i].to];
30 low[k]=min(low[k],low[edge[i].to]);
31 if (low[edge[i].to]<dfn[k])s+=sz[edge[i].to];
32 }
33 else{
34 if (edge[i].to!=fa)low[k]=min(low[k],dfn[edge[i].to]);
35 edge[i].to=0;
36 }
37 if ((mx<a[1].first)&&(sz[k]>=a[1].first)){
38 flag=2;
39 if (n-sz[k]+s<a[1].first){
40 flag=1;
41 return;
42 }
43 if (n-sz[k]+s<a[2].first)swap(a[1],a[2]);
44 ans[k]=a[1].second;
45 a[1].first--;
46 for(int i=head[k];i!=-1;i=edge[i].nex)
47 if ((edge[i].to)&&(low[edge[i].to]>=dfn[k]))update(edge[i].to,1);
48 for(int i=head[k];i!=-1;i=edge[i].nex)
49 if ((edge[i].to)&&(low[edge[i].to]<dfn[k]))update(edge[i].to,1);
50 update(r,2);
51 for(int i=1;i<=n;i++)
52 if (!ans[i])ans[i]=a[3].second;
53 }
54 }
55 int main(){
56 srand(time(0));
57 scanf("%d%d",&n,&m);
58 r=rand()%n+1;
59 for(int i=1;i<=3;i++){
60 scanf("%d",&a[i].first);
61 a[i].second=i;
62 }
63 sort(a+1,a+4);
64 memset(head,-1,sizeof(head));
65 for(int i=1;i<=m;i++){
66 scanf("%d%d",&x,&y);
67 add(x+1,y+1);
68 add(y+1,x+1);
69 }
70 dfs(r,0);
71 for(int i=1;i<=n;i++)printf("%d ",ans[i]);
72 }

[loj3176]景点划分的更多相关文章

  1. <题解>[IOI2019]景点划分

    题目传送门(luogu) 题目传送门(loj) 这个题对我来说可以算是超出了我的能力范围 被学长拿来教我做构造,构造题真简单,构造题真是人,构造题真能手切... 首先对于本题,必须要知道dfs树这东西 ...

  2. world.construct(me);

    目录 0 引言 0.1 所谓构造题 0.2 重点是动机 (motivation) 1 实践出真知 1.1 「CSP-S 2021」「洛谷 P7915」回文 1.1.1 题目大意 1.1.2 解题过程 ...

  3. [LeetCode] Partition List 划分链表

    Given a linked list and a value x, partition it such that all nodes less than x come before nodes gr ...

  4. SWMM模型子汇水区划分的几种方法

    子汇水区的划分是SWMM模型建模的主要步骤之一,划分的好坏对结果精度有比较大的影响.概括来讲,子汇水区的划分有以下几种思路: (1)根据管网走向.建筑物和街道分布,直接人工划分子汇水区.这个方法适用于 ...

  5. 等价类划分方法的应用(jsp)

    [问题描述] 在三个文本框中输入字符串,要求均为1到6个英文字符或数字,按submit提交. [划分等价类] 条件1: 字符合法; 条件2: 输入1长度合法; 条件3: 输入2长度合法: 条件4: 输 ...

  6. Java上等价类划分测试的实现

    利用JavaFx实现对有效等价类和无效等价类的划分: 代码: import javafx.application.Application;import javafx.event.ActionEvent ...

  7. ENode框架Conference案例分析系列之 - 上下文划分和领域建模

    前面一片文章,我介绍了Conference案例的核心业务,为了方便后面的分析,我这里再列一下: 业务描述 Conference是这样一个系统,它提供了一个在线创建会议以及预订会议座位的平台.这个系统的 ...

  8. Cesium原理篇:2最长的一帧之网格划分

    上一篇我们从宏观上介绍了Cesium的渲染过程,本章延续上一章的内容,详细介绍一下Cesium网格划分的一些细节,包括如下几个方面: 流程 Tile四叉树的构建 LOD 流程 首先,通过上篇的类关系描 ...

  9. 两种交换机配置模式,以配置基于端口划分的VLAN为例

    关于交换机的配置模式,大体上可以分为两类:其一以CISCO交换机为代表的配置模式,其二以Huawei.H3C交换机为代表的配置模式.其实这两种配置模式并没有本质的不同,只是配置的命令名称和配置方式存在 ...

随机推荐

  1. 在Vue中使用JSX,很easy的

    摘要:JSX 是一种 Javascript 的语法扩展,JSX = Javascript + XML,即在 Javascript 里面写 XML,因为 JSX 的这个特性,所以他即具备了 Javasc ...

  2. 2020.5.4-ICPC Pacific Northwest Regional Contest 2019

    A. Radio Prize All boring tree-shaped lands are alike, while all exciting tree-shaped lands are exci ...

  3. 初探JavaScript PDF blob转换为Word docx方法

    PDF转WORD为什么是历史难题 PDF 转Word 是一个非常非常普遍的需求,可谓人人忌危,为什么如此普遍的需求,却如此难行呢,还得看为什么会有这样的一个需求: PDF文档遵循iOS32000的规范 ...

  4. pycharm中的terminal和Windows命令提示符有什么区别?二者用pip安装的包是不是位于相同位置?

    那要看pycharm使用了什么shell,可以在设置->工具->终端里查看shell path.如果使用的是cmd.exe那就没区别.pycharm终端和Windows命令提示符用pip安 ...

  5. Java:重载和重写

    Java:重载和重写 对 Java 中的 重载和重写 这个概念,做一个微不足道的小小小小结 重载 重载:编译时多态,同一个类中的同名的方法,参数列表不同,与返回值无关. 有以下几点: 方法名必须相同: ...

  6. BUAA 2020 软件工程 个人项目作业

    BUAA 2020 软件工程 个人项目作业 Author: 17373051 郭骏 项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 个人项目作业 ...

  7. BUAA 软件工程个人作业

    BUAA 软件工程 个人项目作业 Author: 17373015 乔玺华 教学班级 :005 项目地址:https://github.com/JordenQiao/SE_Homework_Perso ...

  8. 数位dp & 热身训练7

    数位dp 数位dp是一种计数用的dp,一般就是要统计一段区间$[L,R]$内,满足一定条件的数的个数,或者各个数位的个数. 数位dp使得暴力枚举变为满足一定状态的记忆化,更加优秀. 数位dp常常会考虑 ...

  9. STM32单片机的学习方法(方法大体适用所有开发版入门)

    1,一款实用的开发板. 这个是实验的基础,有时候软件仿真通过了,在板上并不一定能跑起来,而且有个开发板在手,什么东西都可以直观的看到,效果不是仿真能比的.但开发板不宜多,多了的话连自己都不知道该学哪个 ...

  10. 洛谷 P2120 [ZJOI2007] 仓库建设

    链接: P2120 题意: 有 \(n\) 个点依次编号为 \(1\sim n\).给出这 \(n\) 个点的信息,包括位置 \(x_i\),所拥有的的物品数量 \(p_i\),在此建设一个仓库的费用 ...