第一行一个正整数 n.
接下来 n − 1 行每行两个个正整数 u, v, 表示有一条连接 u, v 的道路.
一行, 表示最少需要的信标数量.
4
1 2
1 3
1 4
2
样例 1 解释
在村庄 3, 4 放置信标, 四个村庄接收到的定位序列分别为 [1, 1], [2, 2], [0, 2], [2, 0].
如果只在 3 放置, 则村庄 2, 4 接收到的定位序列都是 [2], 不满足要求.
注意定位序列是有序的.
样例 2
见下发文件中的 ex_beacon2.in/out.
对于前 20% 的数据, n ≤ 10;
对于前 45% 的数据, n ≤ 40, 树的形态随机;
对于前 70% 的数据, n ≤ 5000;
对于另 5% 的数据, 不存在一个村庄连接着 3 条或以上的道路;
对于 100% 的数据, 1 ≤ n ≤ 1000000, 1 ≤ u, v ≤ n, 保证数据合法.
题目大意:在一棵树上放标记,使得树上每个点能通过到标记的距离序列的不同被区分开
#include
#include
#define fo(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
const int N=1e6+5;
int n,num,f[N],d[N],last[N];
bool chain[N];
struct edge{int to,next;}e[2*N];
void link(int x,int y)
{
e[++num]=(edge){y,last[x]},last[x]=num;
}
void dfs(int x,int fa)
{
int son=0; bool bz=0;
for(int w=last[x];w;w=e[w].next)
{
int y=e[w].to;
if(y==fa) continue;
++son,dfs(y,x);
f[x]+=f[y];
if(chain[y]) bz=1;
}
if(!son) f[x]=1,chain[x]=1;
if(son==1&&bz) f[x]=1,chain[x]=1;
if(son>1&&bz) f[x]--;
}
int main()
{
freopen("beacon.in","r",stdin);
freopen("beacon.out","w",stdout);
scanf("%d",&n);
fo(i,1,n-1)
{
int x,y;
scanf("%d%d",&x,&y);
link(x,y),link(y,x);
++d[x],++d[y];
}
int rt=1;
fo(i,1,n) if(d[i]>d[rt]) rt=i;
if(!d[rt])
{
putchar('0');
return 0;
}
if(d[rt]<=2)
{
putchar('1');
return 0;
}
dfs(rt,0);
printf("%d",f[rt]);
}