树的直径

树的直径即树上的最长路径

POJ 1849

题目: 有一棵树, 在s结点放两个机器人把树的每条边都走一遍,最后机器人不要求回到出发点。问两个机器人走的路总长之和的最小值是多少?

解:让机器人沿着从起点开始的某一条最远距离路径走,对于路径上的其他子树,机器人需要进入遍历并返回,花费两倍的子树权值和,由于机器人不需要回到起点,所以答案为2∗∑wi−d,d为出发点所能到达的最远距离。同理,如果有两个机器人,那么我们就让他们分别向两条不同的路径走去,这样就正好对应了树的直径的BFS/DFS求法,机器人走的路径就成了树的直径,最终的答案就是2∗∑wi−D,D为树的直径长度

#include<cstdio> //两遍DFS
#include<vector>
#include<iostream>
using namespace std;

struct node
{
    int x,s;
};
int n,k,s,ans,t,x,y,z,sum;
vector<node>v[100010];

void dfs(int x,int fa,int dep)
{
    if(ans < dep)
        ans = dep,t = x;
    for(int i = 0;i < v[x].size(); ++i)
        if(v[x][i].x != fa) dfs(v[x][i].x,x,dep + v[x][i].s);
}

int main()
{
    scanf("%d%d",&n,&k);
    for(int i = 1;i < n; ++i)
    {
        scanf("%d%d%d",&x,&y,&z);
        node t;
        t.x = y,t.s = z;
        v[x].push_back(t);
        t.x = x;
        v[y].push_back(t);
        sum += z * 2;
    }
    dfs(k,0,0);
    //cout<<ans<<endl;
    ans = 0;
    dfs(t,0,0);
    //cout<<ans<<endl;
    cout<<sum - ans<<'\n';
    return 0;
}

 

2019牛客第四场A题

链接:https://ac.nowcoder.com/acm/contest/884/A
来源:牛客网
 

A new city has just been built. There're nnn interesting places numbered by positive numbers from 1to n.

In order to save resources, only exactly n−1roads are built to connect these nnn interesting places. Each road connects two places and it takes 1 second to travel between the endpoints of any road.

There is one person in each of the places numbered x1,x2…xk and they've decided to meet at one place to have a meal. They wonder what's the minimal time needed for them to meet in such a place. (The time required is the maximum time for each person to get to that place.)

输入描述:

 

First line two positive integers, n,k - the number of places and persons.

For each the following n−1 lines, there're two integers a,ba,ba,b that stand for a road connecting place aaa and bbb. It's guaranteed that these roads connected all nnn places.

On the following line there're kkk different positive integers x1,x2…xk separated by spaces. These are the numbers of places the persons are at.

输出描述:

A non-negative integer - the minimal time for persons to meet together.

示例1

输入

复制

4 2
1 2
3 1
3 4
2 4

输出

复制

2

说明

They can meet at place 1 or 3.

备注:

1≤n≤10^5

题目:大意是说树上有k个标记的点,问他们同时出发达到同一点需要的最少时间

答案是D/2 ,D是树的直径

#include <bits/stdc++.h>   //两遍DFS
using namespace std;

int n,k,s,ans,t,x,y;
bool vis[100010];
vector<int>v[100010];

void dfs(int x,int fa,int dep)
{
    if(vis[x] && ans < dep)
        ans = dep,t = x;
    for(int i = 0;i < v[x].size(); ++i)
        if(v[x][i] != fa) dfs(v[x][i],x,dep + 1);
}

int main()
{
    scanf("%d%d",&n,&k);
    for(int i = 1;i < n; ++i)
    {
        scanf("%d%d",&x,&y);
        v[x].push_back(y);
        v[y].push_back(x);
    }
    for(int i = 0;i < k; ++i)
    {
        scanf("%d",&x);
        vis[x] = 1;
        s = x;
    }
    dfs(s,0,1);
    ans = 0;
    dfs(t,0,1);
    cout<<ans<<'\n';
    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值