[ABC219]G

Posted ViKyanite.

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[ABC219]G相关的知识,希望对你有一定的参考价值。

一开始我还想着用什么数据结构去维护的,想了好久没想出来。

其实看范围就应该想到n根号n能过的。

 

题意就是说每个点都有自己的颜色,给你q个操作,每次操作将这个点的颜色扩散给相邻点。问你q个操作之后每个点的颜色是什么。

 

首先我们暴力做复杂度是O(q*m)的这样肯定是不行的,于是我们想到优化。难道我们真的需要每个点都去暴力跑相邻点吗?

于是从这个点出发,如果一个点邻接点太多了,那么我们就用标记把这次操作O(1)化。假设我们设置这个太多的定义就是这个点的度超过了 lmt。

参考博客:https://www.cnblogs.com/Kanoon/p/15312156.html

 

 

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

typedef pair<int, int> pii;
const int inf = 0x3f3f3f3f; ///1061109567
const int maxn = 2e5 + 10;

vector<int> G1[maxn]; ///邻接点
vector<int> G2[maxn]; ///度 >= lmt 的邻接点

pii ans[maxn], tag[maxn]; ///最终答案数组,标记数组

int main() {
    int n, m, q; cin >> n >> m >> q;
    int lmt = sqrt(2*m); ///设置lmt

    for (int i = 1; i <= m; ++ i) {
        int u, v; cin >> u >> v;
        G1[u].push_back(v);
        G1[v].push_back(u);
    }
    ///数组初始化
    for (int i = 1; i <= n; ++ i) {
        ans[i] = tag[i] = {i, -1};
    }

    ///预处理出所有点的邻接点中度大于lmt的点
    for (int u = 1; u <= n; ++ u) {
        for (auto v : G1[u]) {
            if (G1[v].size() >= lmt) {
                G2[u].push_back(v);
            }
        }
    }
    for (int i = 1; i <= q; ++ i) {
        int u; cin >> u;
        ///用大于 lmt的邻接点去更新当前点
        ///因为大于lmt的点我们是打标记,实际上我们并没有更新
        ///所以当这个点拥有大于lmt的点时我们需要更新上来,跟之前暴力更新的值取大

        /// O(2*m / lmt)
        for (auto v : G2[u]) {
            if (ans[u].second < tag[v].second) {
                ans[u] = tag[v];
            }
        }

        /// O(lmt)
        if (G1[u].size() < lmt) { ///当前点度小于lmt,暴力更新
            for (auto v : G1[u]) {
                ans[v] = {ans[u].first, i};
            }
        }
        else { ///大于lmt,打上标记
            tag[u] = {ans[u].first, i};
        }

        ///所以复杂度为 O(q * (2*m / lmt + lmt))
    }
    ///由于小于lmt的点我们已经暴力更新了,剩下的只需要用大于lmt的点去更新当前答案即可
    for (int u = 1; u <= n; ++ u) {
        for (auto v : G2[u]) {
            if (ans[u].second < tag[v].second) {
                ans[u] = tag[v];
            }
        }
        cout << ans[u].first << " \\n"[u == n];
    }

    return 0;
}

 

以上是关于[ABC219]G的主要内容,如果未能解决你的问题,请参考以下文章

[ABC219F]Cleaning Robot

[ABC219H]Candles

[linux][c/c++]代码片段01

宋欣蓉.219.11.9.统计学

python+spark程序代码片段

LFS 系列从零开始 DIY Linux 系统:构建 LFS 系统 - Systemd-219