Reunión P1395 (encuentre la distancia y el mínimo de un punto a todos los puntos del árbol)

Portal de títulos

Título: un árbol de n puntos, n-1 aristas, cada arista tiene un peso de 1, encuentre un punto, de modo que la suma de la distancia desde todos los puntos hasta este punto sea la más pequeña.

Idea: cuando suponemos que el punto 1 es la raíz, el costo total es f [1]. Suponiendo que el punto 2 es el nodo secundario del punto 1, entonces f [2] = f [1] -el número de nodos secundarios del punto 2 + (n- El número de nodos secundarios en el punto 2), porque cuando cambiamos la raíz de 1 a 2, los nodos en el subárbol de 2 contribuyen todos -1, y los otros nodos contribuyen todos +1. Entonces usamos el nodo raíz dfs de 1 bit para encontrar el número de nodos de subárbol de cada nodo, luego dfs calcula el costo al tomar 1 como raíz, y finalmente dfs calcula el costo de cada punto, y finalmente genera el punto de costo mínimo y el costo mínimo Eso es todo Lo principal es que no es fácil pensar en la fórmula.

#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 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 s[N],f[N];
int dfs(int x,int y)
{
    for(int i=head[x];i;i=nxt[i])
    {
        if(to[i]!=y)
            s[x]+=1+dfs(to[i],x);
    }
    return s[x];
}
void dfs2(int x,int y,int z)
{
    f[1]+=z;
    for(int i=head[x];i;i=nxt[i])
    {
        if(to[i]!=y)
            dfs2(to[i],x,z+1);
    }
}
int res,n,pos;
void dfs3(int x,int y)
{
    f[x]=f[y]-(s[x]+1)+n-s[x]-1;
    for(int i=head[x];i;i=nxt[i])
        if(to[i]!=y)
            dfs3(to[i],x);
}
signed main()
{
    IOS;
    cin>>n;
    for(int i=1;i<=n-1;i++)
    {
        int u,v;
        cin>>u>>v;
        add(u,v);add(v,u);
    }
    dfs(1,0);
    for(int i=head[1];i;i=nxt[i])
        dfs2(to[i],1,1);
    for(int i=head[1];i;i=nxt[i])
        dfs3(to[i],1);
    res=f[1];pos=1;
    for(int i=1;i<=n;i++)
    {
        if(f[i]<res)
        {
            res=f[i];
            pos=i;
        }
    }
    cout<<pos<<' '<<res<<endl;
}

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

Supongo que te gusta

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