CF981C Useful Decomposition 树 dfs 二十三 *

本文介绍了一种针对树形结构(无向连通且不含环的图)的有效分解方法,旨在将树的边划分成若干简单路径,确保任意两条路径至少有一个公共顶点,每条边恰好属于一条路径。通过实例解析了算法实现过程及有效性验证。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Useful Decomposition
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Ramesses knows a lot about problems involving trees (undirected connected graphs without cycles)!

He created a new useful tree decomposition, but he does not know how to construct it, so he asked you for help!

The decomposition is the splitting the edges of the tree in some simple paths in such a way that each two paths have at least one common vertex. Each edge of the tree should be in exactly one path.

Help Remesses, find such a decomposition of the tree or derermine that there is no such decomposition.

Input

The first line contains a single integer nn (2n1052≤n≤105) the number of nodes in the tree.

Each of the next n1n − 1 lines contains two integers aiai and bibi (1ai,bin1≤ai,bi≤n, aibiai≠bi) — the edges of the tree. It is guaranteed that the given edges form a tree.

Output

If there are no decompositions, print the only line containing "No".

Otherwise in the first line print "Yes", and in the second line print the number of paths in the decomposition mm.

Each of the next mm lines should contain two integers uiui, vivi (1ui,vin1≤ui,vi≤n, uiviui≠vi) denoting that one of the paths in the decomposition is the simple path between nodes uiui and vivi.

Each pair of paths in the decomposition should have at least one common vertex, and each edge of the tree should be presented in exactly one path. You can print the paths and the ends of each path in arbitrary order.

If there are multiple decompositions, print any.

Examples
input
Copy
4
1 2
2 3
3 4
output
Copy
Yes
1
1 4
input
Copy
6
1 2
2 3
3 4
2 5
3 6
output
Copy
No
input
Copy
5
1 2
1 3
1 4
1 5
output
Copy
Yes
4
1 2
1 3
1 4
1 5
Note

The tree from the first example is shown on the picture below:The number next to each edge corresponds to the path number in the decomposition. It is easy to see that this decomposition suits the required conditions.

The tree from the second example is shown on the picture below:We can show that there are no valid decompositions of this tree.

The tree from the third example is shown on the picture below:The number next to each edge corresponds to the path number in the decomposition. It is easy to see that this decomposition suits the required conditions.

 

 

 题解:当度数大于等于3的点最多只有一个时可以遍历,否则不行。一次dfs找出以那个点为根节点的所有叶子节点(配合vector遍历)
 
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <vector>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
#define debug(a) cout << #a << " " << a << endl
using namespace std;
const int maxn = 1e5 + 10;
const int mod = 1e9 + 7;
typedef long long ll;
ll n, u, v, vis[maxn];
vector<ll> V[maxn], ans;
struct node {
    ll num, val;
}deg[maxn];
bool cmp( node a, node b ) {
    return a.num > b.num;
}
void dfs( ll k, ll last ) {
    vis[k] = 1;
    if( V[k].size() == 1 && V[k][0] == last ) {
        ans.push_back(k);
        return ;
    }
    for( ll i = 0; i < V[k].size(); i ++ ) {
        if( !vis[V[k][i]] ) {
            dfs( V[k][i], k ) ;
        }
    }
    return ;
}
int main(){
    std::ios::sync_with_stdio(false);
    cin >> n;
    memset( vis, 0, sizeof(vis) );
    for( ll i = 1; i <= n; i ++ ) {
        deg[i].val = i;
    }
    for( ll i = 1; i < n; i ++ ) {
        cin >> u >> v;
        deg[u].num ++, deg[v].num ++;
        V[u].push_back(v), V[v].push_back(u);
    }
    sort( deg+1, deg+n+1, cmp );
    if( deg[2].num >= 3 ) {
        cout << "No" << endl;
    } else {
        cout << "Yes" << endl;
        dfs( deg[1].val, -1e9 );
        cout << ans.size() << endl;
        for( ll i = 0; i < ans.size(); i ++ ) {
            cout << deg[1].val << " " << ans[i] << endl;
        }
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/l609929321/p/9250275.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值