Trabajar juntos contra la enfermedad (encontrar el diámetro del árbol)

Tema: le da un árbol de n puntos, cada punto en el árbol tiene un valor y cada borde del árbol tiene una longitud de 1. Para el costo entre dos puntos x, y, el costo de xay puede expresarse como a [x] * (dis (x, y)), requiere dos puntos opcionales para obtener un valor máximo.

Rango de datos : n <= 50000.

Idea: atraviese cada punto directamente, encuentre el punto más alejado de él y luego mantenga el valor máximo . Este método solo puede engañar algunos puntos, porque la complejidad del tiempo es O (n ^ 2).

Hablemos primero de la conclusión: supongamos que la distancia entre los dos puntos más grandes en este árbol es máxima, la distancia entre estos dos puntos se llama diámetro del árbol, luego, para cualquier punto, él está más alejado de él. El punto debe ser uno de los dos puntos finales del diámetro. En cuanto a cómo probar, es mejor pensar por ti mismo. No estoy muy claro.

Encuentre el diámetro del árbol: primero tomamos aleatoriamente un punto como la raíz, encontramos el punto más alejado de él y usamos este punto como uno de los puntos finales, y luego usamos este punto final como la raíz, encontramos el punto más alejado de esta raíz El final del diámetro.

Finalmente, solo necesitamos atravesar cada punto y mantener el valor máximo.

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
const int inf=0x7fffffff;
const int mod=1e9+7;
const int eps=1e-6;
typedef long long ll;
typedef unsigned long long ull;
#define ls p<<1
#define rs p<<1|1
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define endl '\n'
#define null NULL
int a[N];
int head[N],nxt[N],to[N],tot=0;
void add(int u,int v)
{
    nxt[++tot]=head[u];
    to[tot]=v;
    head[u]=tot;
}
int de[N],dee[N],deep[N];
void dfs(int x,int y,int *d)
{
    d[x]=d[y]+1;
    for(int i=head[x];i;i=nxt[i])
    {
        if(to[i]!=y)
        {
            dfs(to[i],x,d);
        }
    }
}
signed main()
{
    IOS;
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    for(int i=1;i<=n-1;i++)
    {
        int u,v;
        cin>>u>>v;
        add(u,v);add(v,u);
    }
    dfs(1,0,de);
    int ma=0,root1=0;
    for(int i=1;i<=n;i++)
    {
        if(de[i]>ma)
        {
            ma=de[i];
            root1=i;
        }
    }
    dfs(root1,0,dee);
    ma=0;
    int root2=0;
    for(int i=1;i<=n;i++)
    {
        if(dee[i]>ma)
        {
            ma=dee[i];
            root2=i;
        }
    }
    dfs(root2,0,deep);
    int res=0;
    for(int i=1;i<=n;i++)
    {
        res=max(res,max(dee[i]-1,deep[i]-1)*a[i]);
    }
    cout<<res<<endl;
}

Publicado 93 artículos originales · ganado elogios 9 · vistas 4203

Supongo que te gusta

Origin blog.csdn.net/Joker_He/article/details/105332218
Recomendado
Clasificación