UVa1670/LA5920 Kingdom Roadmap

ops/2024/10/18 2:27:38/

UVa1670/LA5920 Kingdom Roadmap

  • 题目链接
  • 题意
  • 分析
  • AC 代码

题目链接

  本题是2011年icpc欧洲区域赛东北欧赛区的K题

题意

  输入一个n(n≤100000)个结点的,添加尽量少的边,使得任意删除一条边之后图仍然连通。如下图所示,最优方案用虚线表示。
Kingdom Roadmap

分析

  首先统计叶结点数c,即可知道答案是 ⌈ c 2 ⌉ \lceil\frac{c}2\rceil 2c,然后将叶结点两两配对连边即可,不过注意要优先将不在同一个枝杈的两叶结点配对(看下图就能理解)。
Kingdom Roadmap
  可以遍历每个叶结点找出它连接到的枝杈点,这样就统计出了每个枝杈点有哪些叶结点,然后对每一个枝杈点先拿出一个叶结点做配对,其他叶结点存着等后面再任意配对即可。
  还可以任取一个非叶结点作为根对做dfs遍历,遍历过程遇到叶结点就存起来,将存起来的叶结点看成循环队列则可以发现属于同一个枝杈点的叶结点处在队列连续的一段。这时候就很容易对叶结点做配对了:将第 i i i个叶结点和第 i + ⌊ c 2 ⌋ i+\lfloor\frac{c}2\rfloor i+2c个叶结点配对连边。

AC 代码

  本题UVa数据出问题了,提交必WA,Codeforces上对应的题目是GYM 100085K,可提交(先加上freopen,输入自 kingdom.in ,输出到 kingdom.out)。

  按枝杈点点对叶结点做分类的方法

#include <iostream>
#include <vector>
using namespace std;#define N 100100
int q[N], n; vector<int> g[N], gg[N];void solve() {int c = 0;for (int i=1; i<=n; ++i) g[i].clear(), gg[i].clear();for (int i=1, u, v; i<n; ++i) cin >> u >> v, g[u].push_back(v), g[v].push_back(u);for (int i=1; i<=n; ++i) if (g[i].size() == 1) {int u = g[i][0], p = i, v; ++c;while (g[u].size() == 2) v = u, u = g[u][0]+g[u][1]-p, p = v;gg[u].push_back(i);}cout << (c+1)/2 << endl;int head = 0, tail = 0;for (int i=1; i<=n; ++i) {int s = gg[i].size();if (s>1 && head<tail) cout << q[head++] << ' ' << gg[i].back() << endl, --s;for (int j=0; j<s; ++j) q[tail++] = gg[i][j];}for (int i=head+1; i<tail; i+=2) cout << q[i-1] << ' ' << q[i] << endl;if (c&1) cout << q[0] << ' ' << q[tail-1] << endl;
}int main() {ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);while (cin >> n) solve();return 0;
}

  dfs法

#include <iostream>
#include <vector>
using namespace std;#define N 100100
int q[N], n, c; vector<int> g[N];void dfs(int u, int p = -1) {if (g[u].size() == 1) q[c++] = u;for (int i=g[u].size()-1, v; i>=0; --i) if ((v = g[u][i]) != p) dfs(v, u);
}void solve() {c = 0;for (int i=1; i<=n; ++i) g[i].clear();for (int i=1, u, v; i<n; ++i) cin >> u >> v, g[u].push_back(v), g[v].push_back(u);for (int i=1; i<=n; ++i) if (g[i].size() > 1) {dfs(i); break;}cout << (c+1)/2 << endl;for (int i=0, m=c>>1; i<m; ++i) cout << q[i] << ' ' << q[i+m] << endl;if (c&1) cout << q[0] << ' ' << q[c-1] << endl;
}int main() {ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);while (cin >> n) solve();return 0;
}

http://www.ppmy.cn/ops/100391.html

相关文章

anaconda的power shell和prompt有什么区别?

Anaconda 的 PowerShell 和 Prompt 都是用来与 Anaconda 环境交互的工具&#xff0c;但它们有一些关键的区别&#xff1a; Anaconda Prompt&#xff1a; 是什么&#xff1a;Anaconda Prompt 是一个专门为 Anaconda 环境配置的命令行工具&#xff0c;通常基于 Windows 的 CMD&am…

Win11搭建Angular开发环境

作为一名后端程序员&#xff0c;无论当前的工作是否需要&#xff0c;会一点点前端无疑对自己是有帮助的。今天就来介绍一下如何搭建Angular的开发环境。我也是摸着石头过河&#xff0c;所以很多东西也不熟悉&#xff0c;先按照Angular官网的介绍来配置吧。 这个是Angular最新版…

基于springboot学生综合测评系统设计与实现

博主介绍&#xff1a; 大家好&#xff0c;本人精通Java、Python、C#、C、C编程语言&#xff0c;同时也熟练掌握微信小程序、Php和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我有丰富的成品Java、Python、C#毕设项目经验&#xff0c;能够为学生提供各类…

ActiveMQ指南

入门 官网&#xff1a; http://activemq.apache.org/ ActiveMQ 是Apache出品&#xff0c;最流行的&#xff0c;能力强劲的开源消息总线。ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现。 JMS JMS即Java消息服务&#xff08;Java Message Service&#xf…

生产环境中MapReduce的最佳实践

目录 MapReduce跑的慢的原因 MapReduce常用调优参数 1. MapTask相关参数 2. ReduceTask相关参数 3. 总体调优参数 4. 其他重要参数 调优策略 MapReduce数据倾斜问题 1. 数据预处理 2. 自定义Partitioner 3. 调整Reduce任务数 4. 小文件问题处理 5. 二次排序 6. 使用…

docker使用

yum -y install docker centos 安装docker systemctl start docker 启动docker docker info 显示有多少个容器&#xff0c;开始的容器&#xff0c;停止的容器 docker pull 拉一个镜像 docker images 显示镜像列表 docker run -it docker.io/centos:latest /bin/bash…

Linux 软件编程 数据库与网页

sqlite3数据库操作效率&#xff1a; 1.增加事务机制 2.关闭数据库磁盘同步写入 3.使用预处理SQL语句机制实现提升数据库效率 事务机制&#xff1a; 1.可以提高sqlite处理数据的效率 2.确保数据的一致性 关闭数据库中写同步机制&#xff1a; 在…

Compose 跨页面发送消息使用Channel还是全局ViewModel好?

复杂的app 难免遇到 跨页面传递消息的问题&#xff0c;那么使用 Channel 和全局共享viewModel的形式 对于跨页面传递消息&#xff0c;哪个方案 更好一些呢&#xff1f; AI 回答&#xff1a; 它触及了应用架构设计的核心。让我们比较一下使用 Channel 和全局共享 ViewModel 这…