2020牛客暑期多校训练营(第二场)Cover the Tree
程序员文章站
2022-04-09 10:57:51
Cover the Tree题目大意:给定一个无根树,你需要选择最少数量的链,使得树上的所有边都被至少一条链覆盖。输出最少数量,和对应的解。如果有多解,输出任意一个即可。**输入:第一行:n (1≤n≤2×10^5)接下来n-1行每行包含两个整数u,v(1 ≤u < v ≤n)表示节点u和v之间有一条双向边输出:第一行输出一个整数k,表示覆盖所有边的最少链数接下来k行输出两个数u,v,表示节点u和v之间有一条链样例输入:51 21 32 42 5样例输出:22 3...
Cover the Tree
题目大意:
给定一个无根树,你需要选择最少数量的链,使得树上的所有边都被至少一条链覆盖。输出最少数量,和对应的解。如果有多解,输出任意一个即可。**
输入:
第一行:n (1≤n≤2×10^5)
接下来n-1行每行包含两个整数u,v(1 ≤u < v ≤n)表示节点u和v之间有一条双向边
输出:
第一行输出一个整数k,表示覆盖所有边的最少链数
接下来k行输出两个数u,v,表示节点u和v之间有一条链
样例输入:
5
1 2
1 3
2 4
2 5
样例输出:
2
2 3
4 5
用类似于DFS序的方法将每个叶子节点编号,求出叶子结点个数ans,链的条数就是ans/2向上取整,考虑到每一条边都要被链覆盖,所以第i个叶子节点需要和第ans/2+i个叶子节点相匹配
代码:
#include<bits/stdc++.h>
using namespace std;
const int MAXN=2e6+5;
vector<int> vec[MAXN];
int n,u,v,ans,a[MAXN];
void dfs(int x,int fa)
{
if(vec[x].size()==1) a[++ans]=x;
for(int i=0;i<vec[x].size();i++)
{
int y=vec[x][i];
if(y==fa) continue;
dfs(y,x);
}
}//求叶子节点的数量和顺序
int main()
{
scanf("%d",&n);
for(int i=1;i<n;i++)
{
scanf("%d%d",&u,&v);
vec[u].push_back(v);
vec[v].push_back(u);
}
if(n==2) printf("1\n%d %d\n",u,v);
for(int i=1;i<=n;i++)
if(vec[i].size()>1){dfs(i,-1);break;}
printf("%d\n",(ans+1)/2);
for(int i=1;i<=(ans+1)/2;i++)
printf("%d %d\n",a[i],a[i+ans/2]);
}
本文地址:https://blog.csdn.net/s260127ljy/article/details/107335823
上一篇: 一个简单的游戏框架:资源管理方案
下一篇: 坐标转换成SVG的path路径
推荐阅读
-
2019牛客暑期多校训练营(第二场)H Second Large Rectangle
-
2020牛客暑期多校训练营(第四场)——Basic Gcd Problem
-
2020牛客暑期多校训练营(第五场)
-
2020牛客暑期多校训练营(第九场) The Flee Plan of Groundhog
-
2020牛客暑期多校训练营Groundhog and Apple Tree(树形dp,贪心)
-
2020暑期牛客多校训练营第九场(K)The Flee Plan of Groundhog(lca,树形dp)
-
2020牛客暑期多校训练营(第二场)Cover the Tree
-
2020牛客暑期多校训练营(第一场)H-Minimum-cost Flow
-
2020牛客暑期多校 第一场 F Infinite String Comparision(字符串)
-
Harmony Pairs 2020牛客暑期多校训练营(第六场)