2020牛客暑期多校训练营(第二场)C.Cover the Tree

2020牛客暑期多校训练营(第二场)C.Cover the Tree

题目链接

题目描述

Given an unrooted tree, you should choose the minimum number of chains that all edges in the tree are covered by at least one chain. Print the minimum number and one solution. If there are multiple solutions, print any of them.

输入描述:

The first line contains one integer n   ( 1 ≤ n ≤ 2 × 1 0 5 ) n~(1\leq n \leq 2\times10^5) n (1n2×105), denoting the size of the tree.
Following n − 1 {n-1} n1 lines each contains two integers u , v   ( 1 ≤ u < v ≤ n ) u,v~(1\leq u < v \leq n) u,v (1u<vn), denoting an edge in the tree.
It’s guaranteed that the given graph forms a tree.

输出描述:

The first line contains one integer k {k} k, denoting the minimum number of chains to cover all edges.
Following {k}k lines each contains two integers u , v   ( 1 ≤ u , v ≤ n ) u,v~(1\leq u,v \leq n) u,v (1u,vn), denoting a chain you have chosen. Here u = v {u = v} u=v is permitted, which covers no edge.

示例1

输入

5
1 2
1 3
2 4
2 5

输出

2
2 3
4 5

这题实际上非常水,你要理解题意,就是输出最少的路径,路径包含所有边,这些路径是可以相交的,自己举几个例子就可以轻易发现,只要一对一对地输出叶子结点即可,如果叶子结点数量为奇数将一个点多输出一次即可,AC代码如下:

#include
using namespace std;
typedef long long ll;
const int N=1e5+5;
int n,x,y,d[N];
vector<int>ans;
int main(){
    scanf("%d",&n);
    for(int i=0;i<n-1;i++){
        scanf("%d%d",&x,&y);
        d[x]++,d[y]++;
    }
    for(int i=1;i<=n;i++){
        if(d[i]==1) ans.push_back(i);
    }
    int k=ans.size();
    printf("%d\n",(k+1)/2);
    for(int i=0;i<(k+1)/2;i++) printf("%d %d\n",ans[i],ans[i+k/2]);
    return 0;
}

你可能感兴趣的:(思维,图论,牛客)