当前位置: 代码迷 >> 综合 >> 【树形DP】[AtCoder Petrozavodsk Contest 001 E] Antennas on Tree
  详细解决方案

【树形DP】[AtCoder Petrozavodsk Contest 001 E] Antennas on Tree

热度:61   发布时间:2023-09-27 07:54:23.0

题意:

给出一颗树,在树上选择K个点,再定义一个点的权值为:
其到每一个选中节点的距离所组成的K维向量。
现在要使得所有点的权值互不相同,求最小的K


分析:

首先,必须明确一些性质:
对任意一个点uu<script type="math/tex" id="MathJax-Element-119">u</script>所有邻接点所在的联通块中,至多只有一个联通块中没有被选择点。
这就是本题的核心。

但这个性质是基于一个图的,我们要将其转移到树上,就必须解决连向祖先的联通块的影响。
其实只需要选择一个度数大于等于3的节点作为根就可以了:原因很简单,如果根的度数大于等于3,对任意一个点而言,其连向祖先的联通块中必然有点被选择,就不需要考虑祖先了。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#define SF scanf
#define PF printf
#define MAXN 100010
using namespace std;
vector<int> a[MAXN];
int n,root=-1;
int dfs(int x,int fa){int res=0;int flag=0;for(int i=0;i<a[x].size();i++){if(a[x][i]==fa)continue;int res1=dfs(a[x][i],x);if(res1==0&&flag==1)res++;if(res1==0&&flag==0)flag=1;res+=res1;}return res;
}
int main(){SF("%d",&n);int u,v;for(int i=1;i<n;i++){SF("%d%d",&u,&v);a[u].push_back(v);a[v].push_back(u);}for(int i=0;i<n;i++)if(a[i].size()>=3){root=i;break;}if(root==-1){PF("1");return 0;}PF("%d",dfs(root,-1));
}
  相关解决方案