[Nowcoder] Agamemnon‘s Odyssey | 树的直径

链接
Agamemnon, the great king of Mycenae, was assembling his troops in Aulis to sail to the shores of Troy, when he had a vision of goddess Artemis. In this vision, Agamemnon found out that he had accidentally slain a deer that was sacred to Artemis, and now the goddess swore to make Agamemnon suffer on his voyage to Troy.
Along his route to Troy, Agamemnon was planning to stop at the islands of Crete to gather resources for his formidable army. If Artemis were to find out about the sea routes Agamemnon took, she would use her powers to stop the wind along those routes, leaving Agamemnon and his crew stranded. As the trusty advisor of Agamemnon, you now have to help him devise a path between the islands of Crete that provides the army the maximum amount of resources, without letting Artemis discover the routes you take.
在这里插入图片描述
The N islands of Crete are connected to each other via N−1 sea routes. Along each route, Agamemnon can acquire a certain amount of resources. However, if a route is used more than kk times, Artemis will detect the presence of Agamemnon along that route and stop the wind along that route. So, a feasible plan cannot use any route more than k times.
Given that Agamemnon can start and end at any of the islands of Crete, come up with a feasible plan that maximises Agamemnon’s resource earnings. Note that Agamemnon can only collect resources along a sea route during its first use. He does not earn extra resources from a route on reusing it.

在这里插入图片描述

输入

5 1
1 2 3
2 3 1
1 4 5
1 5 9

输出
14
说明
There are 5 islands in Crete, connected to each other via 4 routes, as shown in the figure: the first connecting island 1 and 2 and allowing Agamemnon to acquire 3 units of resources and so on. In this archipelago, the best plan forAgamemnon is to start at island 4, visit island 1 (acquiring 5 units of resources along the 4→1 route), and then endhis path at island 5 (acquiring another 9 units of resources along the 1→5 route), having earned a total of 14 units of resources.
示例2
输入

5 2
1 2 3
2 3 1
1 4 5
1 5 9

输出
18

题意:
有一棵树, n − 1 n-1 n1条边中,两两之间都有一个边权,可以从任意一个点出发,最多经过每一条边k次,只有第一次经过的时候才会算上边权的贡献,问最大的贡献是多少?

其实这道题是非常简单的,是比较模板的题

首先我们考虑,当 k ⩾ 2 k geqslant 2 k2的情况,我们可以将整棵树遍历过一遍,所以说最大贡献便是所有的边权和
k = = 1 k == 1 k==1的情况下,其实就是树的直径,树的直径上,满足贡献最大

#include <math.h>
#include <iostream>
#include <cstring>
using namespace std;

typedef long long ll;

const int maxn = 2e5 + 7;
int n,k;
struct node{
    int u,v,nex,w;
}e[maxn << 1];
int cnt,head[maxn],u,v,w;
bool vis[maxn];
ll dis[maxn];
void init(){
    cnt = 0;
    for(int i=1;i<=n;i++) head[i] = -1;
}
void add(int u,int v,int w){
    e[cnt].u = u;
    e[cnt].v = v;
    e[cnt].w = w;
    e[cnt].nex = head[u];
    head[u] = cnt ++;
}
void dfs(int u){
    vis[u] = 1;
    for(int i=head[u];~i;i=e[i].nex){
        int to = e[i].v;
        if(vis[to]) continue;
        dis[to] = dis[u] + e[i].w;
        dfs(to);
    }
}
int main(){
    ll sum = 0;
    scanf("%d %d",&n,&k);
    init();
    for(int i=1;i<n;i++){
        scanf("%d%d%d",&u,&v,&w);
        sum += w;
        add(u,v,w);
        add(v,u,w);
    }
    if(k >= 2) {
        cout << sum <<endl;
        return 0;
    }
    memset(vis,0,sizeof vis);
    memset(dis,0,sizeof dis);
    dfs(1);
    ll mx = 0,p = 0;
    for(int i=1;i<=n;i++){
        if(dis[i] > mx){
            mx = dis[i];
            p = i;
        }
    }
    /// p
    memset(vis,0,sizeof vis);
    memset(dis,0,sizeof dis);
    dfs(p);
    mx = 0;
    for(int i=1;i<=n;i++){
        mx = max(mx,dis[i]);
    }
    cout << mx << endl;
    return 0;
}
原文地址:https://www.cnblogs.com/PushyTao/p/15459805.html