P7903 兜心の顶(构造)
P7903 兜心の顶
题目背景
Source:八仙敬酒
- 吕洞宾——醉酒提壶力千钧;
- 铁拐李——旋肘膝撞醉还真;
- 汉钟离——跌步抱坛兜心顶;
- 蓝采和——单提敬酒拦腰破;
- 张果老——醉酒抛杯踢连环;
- 曹国舅——仙人敬酒锁喉扣;
- 韩湘子——擒腕击胸醉吹箫;
- 何仙姑——弹腰献酒醉荡步。
题目描述
给定正整数
同时这棵树需满足:直径
注:
- 树的直径
:https://oi-wiki.org/graph/tree-diameter/ - 树的重心
:https://oi-wiki.org/graph/tree-centroid/ - 树的直径的重心
:将树的直径(一条链)视作一棵树,求其重心(一个点)。
输入格式
第一行输入一个正整数
输出格式
第一行输出一个正整数
接下来
无解输出 -1
。
本题采取 Special Judge,输出任意一组合法解均给分。
样例 #1
样例输入 #1
20
样例输出 #1
20
20 18
1 3
19 12
19 4
16 1
4 1
1 7
16 10
7 20
13 8
10 2
18 13
13 17
14 18
11 19
16 5
2 6
16 9
17 15
样例 #2
样例输入 #2
2
样例输出 #2
-1
提示
样例说明
样例 #1 中直径的重心是
样例 #2 中
数据范围
本题采取捆绑测试。
子任务编号 | 分值 | 特殊性质 |
---|---|---|
无 |
对于
题目大意
构造一棵
分析
我们先构造一个长链作为树的直径,
由于树的直径的重心唯一,
显然 直径应为奇数。
分情况讨论
-
显然直径长度为 时不满足题意。 -
当直径长度为
时:此时,树的直径的重心为
。若要 “满足树的直径的重心不是树的重心” ,那么树的重心可供选取的位置为
或 。当然,这两个位置是等价的假如我们选
:那么为了让
她 成为重心,我们至少要给 一个节点……吗?细看可发现:此时树的重心有
, 两个重心,所以我们至少要给
两个节点。当然,此时树的直径变为了
,不满足题意。 -
当直径长度为
时:此时,树的直径的重心为
。那么现在树的重心可供选取的位置为
( )或 ( )。
当我们选 时,与直径长度为 时同理。当我们选
时,我们可以在此节点上增加至少两个节点(同上)使他成为树的重心。乂~ 多了两个直径 咋办呢?
在
上再加一个点不就完事了嘛~乂~ 直径成偶数了 咋办呢?
为了不让树的直径的重心与树的重心重合,我们只能在
再加一个节点。
最终我们得到了一个完整的大保健 一颗兜心の顶树,ta的直径为
综上,
乂~ 那如果点数比
其实有些熟悉毒瘤题的dalao可能已经想到了,这实际上就是一个菊花图。
给
Elaina's code
Elaina's code
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define Elaina 0
inline int read(){
int x=0,f=1;
char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
return x*f;
}
int n;
main(){
n=read();
if(n<=8) return printf("-1"),Elaina;
printf("%lld\n",n);
printf("1 2\n");
printf("2 3\n");
printf("3 4\n");
printf("4 5\n");
printf("5 6\n");
printf("6 7\n");
for(int i=8;i<=n;++i){
printf("3 %lld\n",i);
}
return Elaina;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本