SDNU_ACM_ICPC_2020_Winter_Practice_5th【解题报告】

F-maki和tree:

一.题目大意:

简洁易懂

二.分析(吐槽):

看完题立马就知道咋做了,这不就是找白色连通块嘛(心里骂一声傻逼题)

hhh,凭着我滴手速飞快地敲完,测样例,过了,自己出样例,也过了!

点击提交,woc 咋 T 了 ??!看我换个姿势再来亿次!

就这样,这道题卡我卡了半年,直到比赛结束也在疯狂 TLE...

赛后看题解,看到统计白色连通块大小这里,卧艹,这TM不是一样的吗!(心里再次骂一声傻逼题)

继续往后看,才发觉到原来是计算答案的时候 T 了,O(n) 被自己硬生生是写成了 O(n^2)

改了第一份 TLE 的代码两行,就 A 了(艹,我TM就是个sd)

对,就是没有分析!(理不直也气不壮)

三.代码实现:

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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值