CF1396E——Distance Matching
以后博客可能一直咕咕咕了。一些做题的思考可能会直接放在代码里而不是单独写博客,因为这样太浪费时间,只有一些比较新的题才会单独写博客
思路:对于这种构造可行解使得权值和恰好为某一值的题,一般都是先求出可以构造出来的最大和最小值,然后从某个极值按照一定方法进行连续修改
我们考虑每一条边对于答案的贡献:若边$E(u,v)$把数分成$U,V$两颗子树,则该边最大的贡献是$min(sz[U],sz[V])$,最小是$sz[U]\mod2$。
$min$太难处理,所以想一种办法把$min$去掉,通过重心的性质(每一个子树的$size$小于等于$\frac{n}{2}$),发现直接取重心就可以把$min$去掉了
所以就可以得到
$$minans=\sum_{i=1}^{n} [i \neq root]sz[i]\mod2$$
$$maxans=\sum_{i=1}^{n} [i \neq root]sz[i]$$
然后仔细想想会发现:答案有解的充要条件是$minans \leq k \leq maxans$且$(maxans-k)\mod2=0$
充分性:通过构造方法证明。
每次取在$size$最大的子树中选取两个$lca$深度最大的点,因为本来两个点都是向字树外连的,现在自己相连,所以$\Delta =2*dep[lca]$,然后删掉那两个点
容易发现这样构造是必定可以从$maxans$变成$minans$的,因为对于$sz[u]\mod2=0$的边,它底下肯定两两配对;对于$sz[u]\mod2=0$,这样的贪心会使得下面只有一个点向上经过它
因为点数始终为偶数,所以从最大子树删掉两个点以后不会使得次大子树的$size$大于$\frac{n}{2}$,上面求$minans,maxans$的式子始终成立
当最后一次$dep[lca]*2>rest$时,因为所有不是叶子节点的点都可以作$lca$,所以$dep$必定连续,即肯定能找到构造出刚好使得$rest=0$的方案。
剩下的点按照$max$的方案,跨子树分别连就可以了
必要性:因为$\Delta =2*dep[lca]$,所以如果不是$k,maxans$不是同奇同偶,一定无解
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=120000;
typedef long long ll;
typedef pair<int,int> pii;
#define mk make_pair
int n; ll k; vector<int> v[N];
int sz[N],dep[N],fa[N],root; ll minn=N,maxn=0;
void dfs1(int u,int f)
{
sz[u]=1; int maxsz=0;
for(int i=0;i<(int)v[u].size();i++)
{
int to=v[u][i]; if(to==f) continue;
dfs1(to,u); sz[u]+=sz[to];
maxsz=max(maxsz,sz[to]);
}
if(minn>max(maxsz,n-sz[u])) minn=max(maxsz,n-sz[u]),root=u;
} int top[N],deg[N];
set<pii> S[N],R;//S维护子树中所有可能作为lca的点(即不是叶子)
void dfs(int u,int from)
{
sz[u]=1;
top[u]=from;
if(from&&(int)v[u].size()-1>=1) S[from].insert(mk(dep[u],u));
for(int i=0;i<(int)v[u].size();i++)
{
int to=v[u][i]; if(to==fa[u]) continue;
if(u==root) from=to; deg[u]++;
dep[to]=dep[u]+1; fa[to]=u;
dfs(to,from); sz[u]+=sz[to];
}
} void del(int x)
{
if(!--deg[fa[x]])
S[top[x]].erase(mk(dep[fa[x]],fa[x]));
} int vis[N];
vector<int> rem;
void dfs3(int u)
{
if(!vis[u]) rem.push_back(u);
for(int i=0;i<(int)v[u].size();i++)
{
int to=v[u][i]; if(to==fa[u]) continue;
dfs3(to);
}
} int main()
{
scanf("%d%lld",&n,&k);
for(int i=1;i<n;i++)
{
int x,y; scanf("%d%d",&x,&y);
v[x].push_back(y); v[y].push_back(x);
}
dfs1(1,-1); dep[root]=0; dfs(root,0);
minn=0,maxn=0;
for(int i=1;i<=n;i++)
if(i!=root) maxn+=sz[i], minn+=sz[i]%2;
if(k>maxn||k<minn||(maxn-k)&1) {puts("NO"); return 0;}
puts("YES");
for(int i=0;i<v[root].size();i++)
{
int to=v[root][i];
if(sz[to]>1) R.insert(mk(sz[to],to));
}
ll rest=maxn-k;
while(rest)
{
int now=R.rbegin()->second; R.erase(--R.end());
int pos=S[now].rbegin()->second;
if(2*dep[pos]>rest)
{
rest/=2;
pos=S[now].lower_bound(mk(rest,0))->second;
vector<int> V; V.clear();
for(int i=0;i<(int)v[pos].size();i++)
{
int to=v[pos][i];
if(to==fa[pos]||vis[to]) continue;
V.push_back(to);
}
if((int)V.size()<2) V.push_back(pos);
printf("%d %d\n",V[0],V[1]); vis[V[0]]=1; vis[V[1]]=1;
rest-=dep[pos];
break;
}
else
{
vector<int> V; V.clear();
for(int i=0;i<(int)v[pos].size();i++)
{
int to=v[pos][i];
if(to==fa[pos]||vis[to]) continue;
V.push_back(to);
}
if((int)V.size()<2) V.push_back(pos); rest-=dep[pos]*2;
printf("%d %d\n",V[0],V[1]); vis[V[0]]=1; vis[V[1]]=1;
del(V[0]); del(V[1]);
}
sz[now]-=2;
if(sz[now]>1) R.insert(mk(sz[now],now));
}
dfs3(root);
int T=(int)rem.size()/2;
for(int i=0;i<T;i++) printf("%d %d\n",rem[i],rem[i+T]);
return 0;
}
CF1396E——Distance Matching的更多相关文章
- [cf1396E]Distance Matching
根据$dis(x,y)=d[x]+d[y]-2d[lca(x,y)]$,由于所有点都出现了1次,距离即$\sum_{i=1}^{n}d_{i}-2\sum d[lca(x,y)]$(以下假设根深度为0 ...
- [atARC087F]Squirrel Migration
对这棵树重心情况分类讨论: 1.若这棵树存在两个重心,分别记作$x$和$y$,如果将$(x,y)$断开,两棵子树大小都相同(都为$\frac{n}{2}$),此时$p_{i}$与$i$必然不同属于一个 ...
- world.construct(me);
目录 0 引言 0.1 所谓构造题 0.2 重点是动机 (motivation) 1 实践出真知 1.1 「CSP-S 2021」「洛谷 P7915」回文 1.1.1 题目大意 1.1.2 解题过程 ...
- 最喜欢的算法(们) - Levenshtein distance
String Matching: Levenshtein distance Purpose: to use as little effort to convert one string into th ...
- Scipy教程 - 距离计算库scipy.spatial.distance
http://blog.csdn.net/pipisorry/article/details/48814183 在scipy.spatial中最重要的模块应该就是距离计算模块distance了. fr ...
- Direct Shot Correspondence Matching
一篇BMVC18的论文,关于semantic keypoints matching.dense matching的工作,感觉比纯patch matching有意思,记录一下. 1. 摘要 提出一种针对 ...
- Matching Networks for One Shot Learning
1. Introduction In this work, inspired by metric learning based on deep neural features and memory a ...
- Hausdorff Distance(豪斯多夫距离)
Hausdorff Distance(豪斯多夫距离) 参考博客:http://cgm.cs.mcgill.ca/~godfried/teaching/cg-projects/98/normand/ma ...
- Minimum edit distance(levenshtein distance)(最小编辑距离)初探
最小编辑距离的定义:编辑距离(Edit Distance),又称Levenshtein距离.是指两个字串之间,由一个转成还有一个所需的最少编辑操作次数.许可的编辑操作包含将一个字符替换成还有一个字符. ...
随机推荐
- 027 01 Android 零基础入门 01 Java基础语法 03 Java运算符 07 逻辑“与”运算符
027 01 Android 零基础入门 01 Java基础语法 03 Java运算符 07 逻辑"与"运算符 本文知识点:Java中的逻辑"与"运算符 逻辑运 ...
- Python基本数据类型详细介绍
Python提供的基本数据类型主要有:布尔类型.整型.浮点型.字符串.列表.元组.集合.字典等等 1.空(None)表示该值是一个空对象,空值是Python里一个特殊的值,用None表示.None不能 ...
- CSG:清华大学提出通过分化类特定卷积核来训练可解释的卷积网络 | ECCV 2020 Oral
论文提出类特定控制门CSG来引导网络学习类特定的卷积核,并且加入正则化方法来稀疏化CSG矩阵,进一步保证类特定.从实验结果来看,CSG的稀疏性能够引导卷积核与类别的强关联,在卷积核层面产生高度类相关的 ...
- springCloud项目搭建
新建父maven项目 groupId:pers.xzp.springCloudartifactId:springCloud 父项目中仅仅需要一个pom文件,用于管理模块的依赖统一.继承等 编辑pom文 ...
- 多测试讲解_009肖sirRF自动化框架安装教程
robot framework:自动化测试框架 Python3.7 RIDE(可视化界面). Wxpython pip(在线下载) . setuptools(在线安装) . 第三方库 第三方库:s ...
- Java第一课!
public class Text { public static void main(String[] args) { int a=100; //赋值a=100 System.out.println ...
- linux centos 04
1.python的虚拟环境 1.将当前机器上的解释器作为一个 本地,复制出的很多歌 虚拟解释器 物理机上的 本体解释器 ,什么事也不做 分身1: 解释器1:虚拟环境1 运行django 1 ...
- CentOS 7基础命令介绍
01 CentOS基础命令介绍 重所周知,Linux是一个主要通过命令行来进行管理的操作系统,即通过键盘输入指令来管理系统的相关操作,包括但不限于编辑文件.启动/停止服务等.这和初学者曾经使用的Win ...
- swoole一键协程
swoole4.x后支持一键协程 加上后,开启一键协程化后,MySQL.Redis.Curl 等操作会变成异步 IO //此行代码后,文件操作,sleep,Mysqli,PDO,streams等都变成 ...
- centos8平台使用dnf/yum管理软件包
一,dnf的用途 centos7开始,DNF 成为了默认的软件包管理器,同时 yum 仍然是可用的 DNF包管理器克服了YUM包管理器的一些瓶颈,提升了用户体验,内存占用,依赖分析,运行速度等方面 D ...