SDNU_ACM_ICPC_2020_Winter_Practice_5th【Problem solving report】

F-maki 和 tree :

1. The main idea of ​​the topic:

Concise and understandable

2. Analysis (Tucao):

After reading the question, you will know what to do right away. Isn't this just looking for a white connecting block (a silly question in my heart)

Hhh, relying on my hand to finish typing quickly, test the sample, passed it, produced the sample by myself, and passed it!

Click submit, what happened to woc? ? ! Watch me change my posture a hundred million times!

In this way, I stuck this question card for half a year, and it was crazy TLE until the end of the game...

Look at the solution after the game, and see the statistics of the size of the white connected blocks. Here, fuck, isn't this TM the same! (I scolded a silly question again in my heart)

I continued to look back and realized that T O (n) was originally when calculating the answer, and it was written by myself. O (n ^ 2)

Changed two lines of the code of the first TLE, it was A (fuck, my TM is an sd)

Yes, there is no analysis! (It's not straight or angry)

3. Code implementation:

#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;
}

 

Guess you like

Origin blog.csdn.net/The___Flash/article/details/104175945