题目链接:点击这里
题目大意:
给出一颗树,求最少要添加多少条边使得所有结点到
1
1
1 号结点的最短路径长度小于等于
2
2
2 (边权全为
1
1
1)
题目分析:
贪心,先处理出各点的深度,按深度从大到小依次将该点的父亲节点与
1
1
1 号点连接即可
连接深度大的节点的父亲节点而不用深度的点是因为,其父亲节点的度是大于该叶子节点的,故连接父亲节点的效率更高
具体细节见代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<set>
#include<map>
#include<queue>
#define ll long long
#define inf 0x3f3f3f3f
#define Inf 0x3f3f3f3f3f3f3f3f
#define int ll
using namespace std;
int read()
{
int res = 0,flag = 1;
char ch = getchar();
while(ch<'0' || ch>'9')
{
if(ch == '-') flag = -1;
ch = getchar();
}
while(ch>='0' && ch<='9')
{
res = (res<<3)+(res<<1)+(ch^48);//res*10+ch-'0';
ch = getchar();
}
return res*flag;
}
const int maxn = 1e6+5;
const int mod = 1e9+7;
const double pi = acos(-1);
const double eps = 1e-8;
const int dx[] = {0,0,1,-1};
const int dy[] = {1,-1,0,0};
struct node{
int dep,id;
friend bool operator < (node a, node b)
{
return a.dep < b.dep;
}
}nod[maxn];
int n,cnt,ans,fa[maxn];
vector<int>g[maxn];
priority_queue<node>qu;
bool vis[maxn];
void dfs(int u,int f)
{
for(auto to:g[u])
{
if(to == f) continue;
fa[to] = u;
nod[to].id = to;
nod[to].dep = nod[u].dep+1;
dfs(to,u);
}
}
signed main()
{
n = read();
for(int i = 1;i < n;i++)
{
int from = read(),to = read();
g[from].push_back(to);
g[to].push_back(from);
}
dfs(1,0);
for(int i = 1;i <= n;i++)
if(nod[i].dep > 2) qu.push(nod[i]);
while(!qu.empty())
{
int h = qu.top().id;qu.pop();
if(vis[h]) continue;
int pos = fa[h];
ans++;vis[pos] = true;
for(auto to:g[pos])
if(!vis[to]) vis[to] = true;
}
cout<<ans<<endl;
return 0;
}