根据$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)

构造:以重心$r$为根,选择$r$的所有儿子中子树大小最大的两个,从这两颗子树中各选一个点匹配并删除,利用重心性质可以使得所有$d[lca(x,y)]=0$,即得到答案最大值$\sum_{i=1}^{n}d_{i}$(距离与根无关)

答案要求为$k$,令$k'=\frac{\sum_{i=1}^{n}d_{i}-k}{2}$(若无法整除2则显然无解),我们要让所有$d[lca(x,y)]$之和为$k'$

构造:选择$r$的所有儿子中最大的1个,若$k'\ge d-1$($d$为该子树深度),则从中选出2个点使得lca深度为$d-1$(选择最深的点和其兄弟,若没有兄弟改为和其父亲),之后$k'-=d-1$,否则找到深度为$k'$且不为叶子的点(必然存在,因为整颗树深度为$d$),将其与其儿子匹配即可

具体实现中,对每颗子树需要支持:1.删除一个点;2.查询某深度的点,用set维护,同时外部还需要用优先队列来维护子树大小,时间复杂度都是$o(n\log_{2}n)$,常数可能稍大

  1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 100005
4 struct ji{
5 int nex,to;
6 }edge[N<<1];
7 set<pair<int,int> >s[N];
8 set<pair<int,int> >::iterator it;
9 priority_queue<pair<int,int> >q;
10 pair<int,int>ans[N];
11 int E,n,r,x,y,z,cnt,head[N],sz[N],mx[N],f[N],d[N];
12 long long m;
13 void add(int x,int y){
14 edge[E].nex=head[x];
15 edge[E].to=y;
16 head[x]=E++;
17 }
18 void dfs(int k,int fa){
19 sz[k]=1;
20 mx[k]=0;
21 for(int i=head[k];i!=-1;i=edge[i].nex)
22 if (edge[i].to!=fa){
23 dfs(edge[i].to,k);
24 sz[k]+=sz[edge[i].to];
25 mx[k]=max(mx[k],sz[edge[i].to]);
26 }
27 if (max(n-sz[k],mx[k])<=n/2)r=k;
28 }
29 void dfs(int k,int fa,int sh){
30 f[k]=fa;
31 d[k]=sh;
32 m-=sh;
33 s[x].insert(make_pair(sh,k));
34 sz[k]=1;
35 for(int i=head[k];i!=-1;i=edge[i].nex)
36 if (edge[i].to!=fa){
37 dfs(edge[i].to,k,sh+1);
38 sz[k]+=sz[edge[i].to];
39 }
40 }
41 int main(){
42 scanf("%d%lld",&n,&m);
43 memset(head,-1,sizeof(head));
44 for(int i=1;i<n;i++){
45 scanf("%d%d",&x,&y);
46 add(x,y);
47 add(y,x);
48 }
49 dfs(1,0);
50 for(int i=head[r];i!=-1;i=edge[i].nex){
51 x=edge[i].to;
52 dfs(x,r,1);
53 q.push(make_pair(sz[x],x));
54 }
55 if ((m>0)||(m%2)){
56 printf("NO");
57 return 0;
58 }
59 m/=-2;
60 while (m){
61 x=q.top().second;
62 q.pop();
63 if (sz[x]<2){
64 printf("NO");
65 return 0;
66 }
67 sz[x]-=2;
68 if (sz[x])q.push(make_pair(sz[x],x));
69 if ((*--s[x].end()).first-1<=m){
70 y=(*--s[x].end()).second;
71 s[x].erase(--s[x].end());
72 m-=d[y]-1;
73 z=f[y];
74 bool flag=0;
75 for(int i=head[z];i!=-1;i=edge[i].nex)
76 if ((edge[i].to!=f[z])&&(edge[i].to!=y)&&(s[x].find(make_pair(d[edge[i].to],edge[i].to))!=s[x].end())){
77 ans[++cnt]=make_pair(edge[i].to,y);
78 s[x].erase(make_pair(d[edge[i].to],edge[i].to));
79 flag=1;
80 break;
81 }
82 if (!flag){
83 ans[++cnt]=make_pair(z,y);
84 s[x].erase(make_pair(d[z],z));
85 }
86 }
87 else{
88 it=lower_bound(s[x].begin(),s[x].end(),make_pair((int)m,0));
89 while ((*it).first==m){
90 bool flag=0;
91 y=(*it).second;
92 for(int i=head[y];i!=-1;i=edge[i].nex)
93 if ((edge[i].to!=f[y])&&(s[x].find(make_pair(d[edge[i].to],edge[i].to))!=s[x].end())){
94 ans[++cnt]=make_pair(y,edge[i].to);
95 s[x].erase(make_pair(d[y],y));
96 s[x].erase(make_pair(d[edge[i].to],edge[i].to));
97 flag=1;
98 break;
99 }
100 if (flag)break;
101 it++;
102 }
103 m=0;
104 }
105 }
106 while (!q.empty()){
107 x=q.top().second;
108 q.pop();
109 if (q.empty()){
110 ans[++cnt]=make_pair((*s[x].begin()).second,r);
111 break;
112 }
113 y=q.top().second;
114 q.pop();
115 if (sz[x]>1)q.push(make_pair(--sz[x],x));
116 if (sz[y]>1)q.push(make_pair(--sz[y],y));
117 ans[++cnt]=make_pair((*s[x].begin()).second,(*s[y].begin()).second);
118 s[x].erase(s[x].begin());
119 s[y].erase(s[y].begin());
120 }
121 printf("YES\n");
122 for(int i=1;i<=cnt;i++)printf("%d %d\n",ans[i].first,ans[i].second);
123 }

[cf1396E]Distance Matching的更多相关文章

  1. CF1396E——Distance Matching

    传送门:QAQQAQ(题面翻译) 以后博客可能一直咕咕咕了.一些做题的思考可能会直接放在代码里而不是单独写博客,因为这样太浪费时间,只有一些比较新的题才会单独写博客 思路:对于这种构造可行解使得权值和 ...

  2. [atARC087F]Squirrel Migration

    对这棵树重心情况分类讨论: 1.若这棵树存在两个重心,分别记作$x$和$y$,如果将$(x,y)$断开,两棵子树大小都相同(都为$\frac{n}{2}$),此时$p_{i}$与$i$必然不同属于一个 ...

  3. world.construct(me);

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

  4. 最喜欢的算法(们) - Levenshtein distance

    String Matching: Levenshtein distance Purpose: to use as little effort to convert one string into th ...

  5. Scipy教程 - 距离计算库scipy.spatial.distance

    http://blog.csdn.net/pipisorry/article/details/48814183 在scipy.spatial中最重要的模块应该就是距离计算模块distance了. fr ...

  6. Direct Shot Correspondence Matching

    一篇BMVC18的论文,关于semantic keypoints matching.dense matching的工作,感觉比纯patch matching有意思,记录一下. 1. 摘要 提出一种针对 ...

  7. Matching Networks for One Shot Learning

    1. Introduction In this work, inspired by metric learning based on deep neural features and memory a ...

  8. Hausdorff Distance(豪斯多夫距离)

    Hausdorff Distance(豪斯多夫距离) 参考博客:http://cgm.cs.mcgill.ca/~godfried/teaching/cg-projects/98/normand/ma ...

  9. Minimum edit distance(levenshtein distance)(最小编辑距离)初探

    最小编辑距离的定义:编辑距离(Edit Distance),又称Levenshtein距离.是指两个字串之间,由一个转成还有一个所需的最少编辑操作次数.许可的编辑操作包含将一个字符替换成还有一个字符. ...

随机推荐

  1. python自定义翻页配置

    1.创建pager.py文件,针对翻页进行函数书写 class PageInfo(object): # current_page 当前页数 # all_count 所有行 # per_page 每页的 ...

  2. 洛谷4051 JSOI2007 字符加密(SA)

    真是一道良好的SA模板题 首先,由于涉及到从左边移动到右边这个过程,我们不妨直接把字符串复制一遍,接在后面. 然后直接构造后缀数组,按排名从小到大,枚举所有的位置,如果这个后缀的起始点是在原串中的,那 ...

  3. pycharm中设置自己的文件模板

    File>>Settings>>Editor>>File and Code Templates 选择文件类型Python Scripts,输入文件模板类型 #!/u ...

  4. RPAaaS是什么?为何能够推进RPA人人可用?

    RPAaaS是什么?为何能够推进RPA人人可用? 助力中小企业快速实现自动化,RPAaaS加速"RPA人人可用"时代到来 相对传统RPA拥有更多优势,PRAaaS为RPA行业带来更 ...

  5. perl打开读取文件(open)

    在Perl中可以用open或者sysopen函数来打开文件进行操作,这两个函数都需要通过一个文件句柄(即文件指针)来对文件进行读写定位等操作.下面以open函数为例:1:读:open(文件句柄,&qu ...

  6. (课内)信安数基RSA-level3-5

    emmmm感觉其实自己对这个的理解完全不够,原理只能写出这么个东西(悲) 代码完全是 攻击方式中(1)(2)内容的实现. lambda是一种可以理解为匿名函数的写法:写在这里看起来很酷炫(bushi) ...

  7. python反序列化1(__reduce__)

    part1:不求甚解的复现 对于服务端源码:    编写恶意序列化对象生成程序: 将生成的恶意序列化对象输入服务端user,使其执行系统命令.(上面那俩其实都行) part2:原理解释 b'xxx'是 ...

  8. [对对子队]会议记录4.21(Scrum Meeting12)

    今天已完成的工作 吴昭邦 ​ 工作内容:基本实现改变顺序合成 ​ 相关issue:实现流水线合成系统的逻辑 ​ 相关签入:4.21签入1 梁河览 ​ 工作内容:修改设置界面bug ​ 相关签入:4.2 ...

  9. Flutter的环境配置以及一些常见问题

    flutter & AndroidStudio flutter的下载与配置 flutter是Google推出的基于Dart语言开发的跨平台开源UI框架,能够支持安卓与iOS. flutter框 ...

  10. [软工顶级理解组] Alpha阶段事后分析

    目录 设想和目标 计划 资源 变更管理 设计/实现 测试/发布 团队的角色,管理,合作 总结 质量提高 会议截图 设想和目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰 ...