Krypton Belt East

Título: Krypton Gold Belt East
Tema: Originalmente había una computadora (número 1) en el laboratorio. Recientemente Krypton Gold Belt Gugudong compró computadoras N-1 para el laboratorio, numeradas del 2 al N. Cada computadora está conectada a una computadora previamente instalada con un cable de red. Pero Gugudong está preocupado de que la velocidad de la red sea demasiado lenta, quiere saber la longitud máxima del cable desde la i-ésima computadora a otras computadoras, pero el pobre Gugudong acaba de sufrir un ataque inteligente de rayos cósmicos no hace mucho. Por favor, ayúdelo.
Inserte la descripción de la imagen aquí
Consejo: La entrada de muestra corresponde a esta figura. De esta figura, puede ver que la computadora más alejada de la computadora 1 es la computadora 4, y la distancia entre ellas es 3. La Computadora No. 4 y la Computadora No. 5 son los puntos más lejanos de la Computadora No. 2, entonces la respuesta es 2. La Computadora No. 5 está más alejada de la Computadora No. 3, entonces para la Computadora No. 3, su respuesta es 3. Del mismo modo, podemos calcular que la respuesta para la computadora 4 y la computadora 5 es 4.

Entrada: el
archivo de entrada contiene múltiples conjuntos de datos de prueba. Para cada conjunto de datos de prueba, la primera línea es un número entero N (N <= 10000), luego hay líneas N-1, dos números en cada línea, y para los dos números en la línea i-ésima, representan el número conectado a la computadora i El número de la computadora y la longitud del cable de red entre ellos. La longitud total del cable de red no excederá de 10 ^ 9, y cada número está separado por un espacio.

Salida:
para cada conjunto de datos de prueba, se emiten N líneas y la línea i-ésima indica la respuesta de la computadora i (1 <= i <= N).

: :
Muestra de entrada
5
1 1
2 1
3 1
1 1
Muestra de salida
3
2
3
4
4

Ideas para resolver problemas: en primer lugar, puede pensar en este gráfico como un árbol; luego, el punto más alejado de cada punto del árbol debe ser dos puntos del diámetro del árbol; aquí hay una prueba: puede expandir el árbol para que El más largo es similar a:
Inserte la descripción de la imagen aquí

Se puede ver claramente que el lado más largo (suponiendo que el lado es 1 y el lado no es uno también se puede hacer); si el punto con la distancia más larga desde un cierto punto no es el punto final izquierdo y derecho que se muestra en la figura anterior, entonces esto La expansión no es la más larga, lo que está en contradicción con la expansión más larga. Por ejemplo, si hay un punto cuya distancia es la más alejada es el punto del lado pequeño que se bifurca en la figura anterior, entonces el punto final derecho debe estar más lejos, lo que produce Contradicción; de esta manera, primero encuentre los dos puntos finales de ese diámetro, luego dfs en ambos lados, encuentre la distancia máxima desde cada punto a estos dos puntos finales, esta distancia es la distancia máxima requerida;

Código de arriba:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define ll long long
using namespace std;
struct node
{
    ll to;
    ll next;
    ll w;
}e[20005];
ll head[20005]={0},tot=0,vis[20005]={0},v1,v2,maxn=-1,d[20005]={0};
void chushihua()
{
    memset(head,0,sizeof(head));
    memset(vis,0,sizeof(vis));
    memset(d,0,sizeof(d));
    tot=0;
    maxn=-1;
}
void add(ll x,ll y,ll s)
{
    e[++tot].to=y;
    e[tot].next=head[x];
    e[tot].w=s;
    head[x]=tot;
}
void dfs(ll t,ll li)
{
    for(ll i=head[t];i;i=e[i].next)
    {
        ll x=e[i].to;
        if(vis[x]!=1)
        {
            ll h=li+e[i].w;
            vis[x]=1;
            if(maxn<h)
            {
                maxn=h;
                v1=x;
            }
            dfs(x,h);
        }
    }
}
void dfs1(ll t,ll li)
{
    for(ll i=head[t];i;i=e[i].next)
    {
        ll x=e[i].to;
        if(vis[x]!=1)
        {
            ll h=li+e[i].w;
            vis[x]=1;
            d[x]=max(d[x],h);
            dfs1(x,h);
        }
    }
}
int main()
{
    ll n;
    while(scanf("%lld",&n)!=EOF)
    {
        chushihua();//初始化
        for(ll i=2;i<=n;i++)//利用前向星存边
        {
            ll y,v;
            scanf("%lld%lld",&y,&v);
            add(i,y,v);
            add(y,i,v);
        }
        vis[1]=1;//先标记开始搜的点
        dfs(1,0);//先搜其中一个端点
        memset(vis,0,sizeof(vis));//初始化
        maxn=-1;
        v2=v1;
        vis[v2]=1;
        dfs(v2,0);//另外一个
        memset(vis,0,sizeof(vis));
        maxn=-1;
        vis[v1]=1;
        dfs1(v1,0);//遍历两边后就可以了;
        memset(vis,0,sizeof(vis));
        maxn=-1;
        vis[v2]=1;
        dfs1(v2,0);
        for(ll i=1;i<=n;i++)
        {
            printf("%lld\n",d[i]);
        }
    }
}
PGZ
Publicado 34 artículos originales · me gusta 0 · visitas 873

Supongo que te gusta

Origin blog.csdn.net/qq_43653717/article/details/105150916
Recomendado
Clasificación