(2020牛客暑期多校训练营)[二]Cover the Tree

题目描述:
给定一个无根树,你需要选择最少数量的链,使得树上的所有边都被至少一条链覆盖。输出最少数量,和对应的解。如果有多解,输出任意一个即可。
样例:
输入
5
1 2
1 3
2 4
2 5
输出
2
2 3
4 5
思路:
dfs寻找叶子结点,并标上号,记叶子结点的总个数为ans。第i和叶子结点与第i+(ans+1)/2个
叶子结点相连。若剩下一个叶子结点,则这个叶子结点与其他任意一个叶子结点相连即可。
代码如下:
#include
using namespace std;
int n,u,v,ans;
vector a[200010];
int b[200010];
void dfs(int k,int c)
{
for(int i=0;i if(a[k][i]!=c)
dfs(a[k][i],k);
if(a[k].size()==1) b[++ans]=k;
}
int main()
{
scanf("%d",&n);
for(int i=1;i {
scanf("%d%d",&u,&v);
a[u].push_back(v);
a[v].push_back(u);
}
for(int i=1;i<=n;i++)
if(a[i].size()>=1)
{
dfs(i,i);
break;
}
printf("%d\n",(ans+1)/2);
for(int i=1;i<=ans/2;i++) printf("%d %d\n",b[i],b[(ans+1)/2+i]);
if(ans%2) printf("%d %d",b[1],b[ans/2+1]);
}

你可能感兴趣的:((2020牛客暑期多校训练营)[二]Cover the Tree)