CF981C Useful Decomposition树/思维
Posted Roni
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF981C Useful Decomposition树/思维相关的知识,希望对你有一定的参考价值。
【链接】:CF
【题意】:给定一棵树,要求拆成若干条简单路径,并且这些路径都经过一个公共节点。给出任意一个解决方案,如不存在输出No。
【分析】:
因为是一棵树, 所以如果要求任意两条路线至少有一个公共点, 到最后, 所有的路线都会有唯一的公共点. 如果有两个公共点的话, 就至少有两条路线只包含其中的一条路线, 否则就会有环, 有了环就不是树了.
也就是说, 所有的点, 除了那个唯一的公共点, 必须度数小于 2 .
在所有点之中:
度数为 1 的点是路线的一个端点.
度数为 2 的是一条路线中除了两端以外的点.
度数大于 2 的是路线的公共点. 如果有两个及以上的点的度数是大于 2 的, 代表不可能路线中任意两条至少交于一点, 输出 No.
如果没有度数大于 2 的点, 代表只有一条路线.
如何输出路线:
先输出 Yes, 代表可以将树分解.
接着输出路线的个数, 也就是度数为 1 的点的个数.
接着, 对于每条路线, 输出其中一个度数为 1 的点和 唯一的 公共点.
注意: 如果没有度数大于 2 的点, 代表只有一条路线, 此时路线个数并不等于度数为 1 的点的个数, 并且端点就是两个度数为 1 的点.
【代码】:
#include <bits/stdc++.h>
using namespace std;
int n;
int deg[100005]; // 每个点的度数
int leaves[100005], comv[100005]; // leaves 存储度数为 1 的端点, comv 存储公共点
int nleaf = 0, ncomv = 0; // 存储度数为 1 的点与公共点的数量
int x,y;
/*
有三种可能情况:
所有链在某一点上相交,也就是只有一个点度数>2;
只有一条链,就是两个点度数为1,其他点度数为2;
不符合要求的情况,就是有超过一个点度数>2
*/
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
deg[x]++,deg[y]++;
}
for(int i=1;i<=n;i++)
{
if(deg[i]==1) leaves[++nleaf]=i;
else if(deg[i]>2) comv[++ncomv]=i;
}
//如果公共点不唯一, 就输出 "No"
if(ncomv>1) {printf("No\n");return 0;}//不符合要求的情况,就是有超过一个点度数>2
printf("Yes\n");
// 如果只有一条路线, 就输出两端 (即两个度数为 1 的点)
if(ncomv==0) printf("1\n%d %d\n",leaves[1],leaves[2]);//只有一条链,就是两个点度数为1,其他点度数为2;
else//所有链在某一点上相交,也就是只有一个点度数>2;
{
printf("%d\n",nleaf);//度数为1的点的个数
for(int i=1;i<=nleaf;i++)
{
printf("%d %d\n",comv[1],leaves[i]);//公共点与一个度数为1的点
}
}
return 0;
}
以上是关于CF981C Useful Decomposition树/思维的主要内容,如果未能解决你的问题,请参考以下文章