[NOI2003] 逃学的小孩

从一棵树中找出三个点 (x,y,z),使 (min(dis[x][z],dis[y][z])+dis[x][y]) 最大

Solution

直觉找直径当 (x,y),暴力枚举 (z) 算答案即可

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

#define int long long
const int N = 500005;

struct edge {int v,w;};

vector <edge> g[N];
int dis[N],ans[N],n,t1,t2,t3,r;

void dfs(int p) {
    for(edge e:g[p]) {
        int q=e.v, w=e.w;
        if(dis[q]==0&&q!=r) {
            dis[q]=dis[p]+w;
            dfs(q);
        }
    }
}

signed main() {
    ios::sync_with_stdio(false);
    cin>>n>>t1;
    for(int i=1;i<n;i++) {
        cin>>t1>>t2>>t3;
        g[t1].push_back({t2,t3});
        g[t2].push_back({t1,t3});
    }
    r=1; dfs(1);
    int p=max_element(dis+1,dis+n+1)-dis;
    memset(dis,0,sizeof dis);
    r=p; dfs(p);
    int q=max_element(dis+1,dis+n+1)-dis;
    memcpy(ans,dis,sizeof dis);
    memset(dis,0,sizeof dis);
    r=q; dfs(q);
    int tans=0;
    for(int i=1;i<=n;i++) if(i!=p && i!=q)
        tans=max(tans,min(ans[i],dis[i]));
    cout<<ans[q]+tans;
}

原文地址:https://www.cnblogs.com/mollnn/p/12541150.html