SDNU_ACM_ICPC_2020_Winter_Practice_5th 【Informe de resolución de problemas】

F-maki 和 árbol :

1. La idea principal del tema:

Conciso y comprensible

2. Análisis (Tucao):

Después de leer la pregunta, sabrá qué hacer de inmediato. ¿No es esto solo buscar un bloque de conexión blanco (una pregunta tonta en mi corazón)

¡Hhh, confiando en mi mano para terminar de escribir rápidamente, probar la muestra, pasarla y producir la muestra yo también!

Haga clic en enviar, ¿qué pasó con woc? ? ! ¡Mírame cambiar de postura cien millones de veces!

De esta manera, pegué esta tarjeta de preguntas durante medio año, y fue una locura TLE hasta el final del juego ...

Mire la solución después del juego, y vea las estadísticas del tamaño de los bloques blancos conectados. Aquí, carajo, ¿no es esto TM lo mismo? (Regañé una pregunta tonta de nuevo en mi corazón)

Seguí mirando hacia atrás y me di cuenta de que T En) era originalmente cuando calculaba la respuesta, y estaba escrito por mí mismo. O (n ^ 2)

Se cambiaron dos líneas del código del primer TLE, era A (joder, mi TM es un sd)

¡Sí, no hay análisis! (No es recto ni enojado)

3. Implementación del código:

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

typedef long long ll;

const int M = (int)1e5;

int n;
int cnt;
int head[M + 5];
struct node
{
    int v, nx;
}Edge[M * 2 + 5];

char color[M + 5];

int fa[M + 5];
int sz[M + 5];

void init()
{
    cnt = 0;
    for(int i = 1; i <= n; ++i)
    {
        head[i] = -1;
        fa[i] = i;
        sz[i] = 1;
    }
}

void add(int u, int v)
{
    Edge[cnt].v = v;
    Edge[cnt].nx = head[u];
    head[u] = cnt++;
}

void dfs(int u, int fa)
{
    ::fa[u] = ::fa[fa];
    for(int i = head[u]; ~i; i = Edge[i].nx)
    {
        int v = Edge[i].v;
        if(v == fa || color[v] == 'B')  continue;
        dfs(v, u);
        sz[u] += sz[v];
    }
}

int main()
{
    scanf("%d", &n);
    init();
    scanf("%s", color + 1);
    for(int i = 0, u, v; i < n - 1; ++i)
    {
        scanf("%d %d", &u, &v);
        add(u, v);
        add(v, u);
    }
    for(int i = 1; i <= n; ++i)
    {
        if(fa[i] == i && color[i] == 'W')
            dfs(i, i);
    }
    ll ans = 0;
    for(int i = 1; i <= n; ++i)
    {
        if(color[i] == 'B')
        {
            int sum = 0;
            for(int j = head[i]; ~j; j = Edge[j].nx)
            {
                int v = Edge[j].v;
                if(color[v] == 'W')
                {
                    v = fa[v];
                    ans += 1ll * (sum + 1) * sz[v];
                    sum += sz[v];
                }
            }
        }
    }
    printf("%lld\n", ans);
    return 0;
}

 

Supongo que te gusta

Origin blog.csdn.net/The___Flash/article/details/104175945
Recomendado
Clasificación