[ABC219]G - Propagation

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

其实看范围就应该想到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;
}
复制代码

 

posted @   ViKyanite  阅读(111)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示
主题色彩