题意:给你一棵N个结点的树,然后输入N-1条边。要求将该树拆成若干条简单路径,并且这些路径都经过一个公共节点。给出任意一个解决方案,如不存在输出No。
思路:邻接表存图建双向边,如果一个点的出度>2,那么他就是那个共享的点,如果有两个共享的点,一定为NO。
我们把出度为1的点,存到一个数组中。如果有共享点,直接输出:共享点~这个数组中所有的点即可。
如果没有共享点,那么就是一条链的情况,输出两个出度为1的点即可。
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100005;
int n, xx;
vector<int> G[MAXN], s;
int main()
{
scanf("%d", &n);
for (int i = 0; i < n-1; i++)
{
int u, v; scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
vector<int> x;
int cnt = 0, s = 0;
for (int i = 1; i <= n; i++)
{
if (G[i].size() == 1) x.push_back(i);
if (G[i].size() > 2) s = i, cnt++;
}
if (cnt >= 2) printf("No\n");
else
{
printf("Yes\n");
if (s == 0)//没有分叉点即一条链的情况
{
printf("%d\n", 1);
printf("%d %d\n", x[0], x[1]);
}
else
{
printf("%d\n", x.size());
for (auto i: x) printf("%d %d\n", s, i);
}
}
return 0;
}