Tree with Small Distances ----CodeForces - 1029E贪心

You are given an undirected tree consisting of nn vertices. An undirected tree is a connected undirected graph with n−1n−1 edges.
Your task is to add the minimum number of edges in such a way that the length of the shortest path from the vertex 11 to any other vertex is at most 22. Note that you are not allowed to add loops and multiple edges.

Input
The first line contains one integer nn (2≤n≤2⋅1052≤n≤2⋅105) — the number of vertices in the tree.
The following n−1n−1 lines contain edges: edge ii is given as a pair of vertices ui,viui,vi (1≤ui,vi≤n1≤ui,vi≤n). It is guaranteed that the given edges form a tree. It is guaranteed that there are no loops and multiple edges in the given edges.

Output
Print a single integer — the minimum number of edges you have to add in order to make the shortest distance from the vertex 11 to any other vertex at most 22. Note that you are not allowed to add loops and multiple edges.

Examples
Input
7
1 2
2 3
2 4
4 5
4 6
5 7
Output
2
Input
7
1 2
1 3
2 4
2 5
3 6
1 7
Output
0
Input
7
1 2
2 3
3 4
3 5
3 6
3 7
Output
1

题意:给一个树加最少的边,使得1到所有点的距离小于等于2.
记录到1结点的距离
肯定是从最后一层开始遍历
考虑加边的话,加到哪个结点会更优,自然是父亲结点,因为这样的话可以把这个节点的父节点以及父节点的父节点都变成符合条件的点 , 从最后一层起找>2的点把父节点连起来

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<queue>
#include<cmath>
#include<vector>
#define INF 0x3f3f3f3f
using namespace std;

vector<int>M[1000010];

int dep[1000100],n,x,y,ans;

void dfs(int x,int father,int step)
{
    dep[x] = step;
  //  int flag = 0;
    int l = M[x].size();
    for(int i = 0;i < l; ++i)
    {
        if(M[x][i] == father) continue;
        dfs(M[x][i] , x , step + 1);
        if(dep[M[x][i]] > 2)
        {
           // ans++;  ans不能直接加,会加重,也不能加完break,上面的dfs遍历不完
           flag = 1;
            dep[x] = 1;
            dep[father] = 2;
            //break;
        }
    }
    ans += flag;
    //printf("ans = %d ",ans);
}

int main()
{
    scanf("%d",&n);
    ans = 0;
    for(int i = 1;i < n; ++i)
    {
        scanf("%d%d",&x,&y);
        M[x].push_back(y);
        M[y].push_back(x);
    }
    dfs(1,1,0);
    printf("%d\n",ans);
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值