zoukankan      html  css  js  c++  java
  • 【2020牛客多校】2020牛客暑期多校训练营(第三场)G-Operating on a Graph——傻逼暴力题

    G-Operating on a Graph

    题目链接

    大致题意

    给你一个图,有 (n) 个点,(m) 条边,点的下标从 (0 ightarrow n - 1)
    对于点 (i) ,其开始时属于 (i-group)
    总共操作 (q) 次,每次操作时给出一个 (n) ,将所有与 (n-group) 直接相连的 (group) 加入到 (n-group)
    在所有操作结束后,求每个点所在的 (group)

    简单思路方向

    利用 STLlist 的连接,list 模拟 queue,然后用并查集做

    具体思路

    首先,(group) …………这不就是并查集吗…………
    只不过其提供的边不可以一下子拿来 unite 只能一层层 unite (从 (BFS) 的角度考虑,这个层的意思)
    那么可以为每个 (group) 上保存一个 queue ,然后每次使用这个 queue 来进行一层的 (BFS)

    但是考虑到两个 (group) 联合之后导致其中一个 (group)queue 的数据应该与另外一个合并,而 queue 的合并效率太低,所以使用 list 来模拟 queue,因为 listsplice 方法,效率非常高

    其次为了避免重复 (BFS) ,所以增加了 visit 数组

    AC code

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int MAXN = 8e5 + 100;
    
    int f[MAXN];
    list<int> lists[MAXN];
    bool visit[MAXN];
    vector<int> node[MAXN];
    
    int finds(int x) {
        return x == f[x] ? x : f[x] = finds(f[x]);
    }
    
    void unite(int x, int y) {
        int rx = finds(x);
        int ry = finds(y);
        if (rx != ry) {
            f[rx] = ry;
            lists[ry].splice(lists[ry].end(), lists[rx]);
        }
    }
    
    void init(int b, int e) { // 初始化函数,范围为 [b, e)
        for (int i = b; i < e; i++)
            f[i] = i;
    }
    
    void bfs(int cur) {
        if (finds(cur) != cur) return;
        int size = lists[cur].size();
    
        for (int i = 0; i < size; ++i) {
            auto explorer = lists[cur].front();
            for (auto item : node[explorer]) {
                unite(item, cur);
                if (visit[item]) continue;
                lists[cur].push_back(item);
                visit[item] = true;
            }
            lists[cur].pop_front();
        }
    }
    
    void solve() {
        int T;
        cin >> T;
        for (int ts = 0; ts < T; ++ts) {
            int n, m;
            cin >> n >> m;
            memset(visit, false, sizeof(bool) * (n + 5));
            init(0, n + 5);
            for (int i = 0; i < n + 5; ++i) {
                node[i].clear();
                lists[i].clear();
                lists[i].push_back(i);
            }
    
            int u, v;
            for (int i = 0; i < m; ++i) {
                cin >> u >> v;
                node[u].push_back(v);
                node[v].push_back(u);
            }
    
            int q;
            cin >> q;
            for (int i = 0; i < q; ++i) {
                cin >> u;
                bfs(u);
            }
    
            for (int i = 0; i < n; ++i)
                cout << finds(i) << " 
    "[i == n - 1];
        }
    }
    
    signed main() {
        ios_base::sync_with_stdio(false);
        cin.tie(nullptr);
        cout.tie(nullptr);
    #ifdef ACM_LOCAL
        freopen("in.txt", "r", stdin);
        freopen("out.txt", "w", stdout);
        int test_index_for_debug = 1;
        char acm_local_for_debug;
        while (cin >> acm_local_for_debug) {
            if (acm_local_for_debug == '$') exit(0);
            cin.putback(acm_local_for_debug);
            if (test_index_for_debug > 20) {
                throw runtime_error("Check the stdin!!!");
            }
            auto start_clock_for_debug = clock();
            solve();
            auto end_clock_for_debug = clock();
            cout << "Test " << test_index_for_debug << " successful" << endl;
            cerr << "Test " << test_index_for_debug++ << " Run Time: "
                 << double(end_clock_for_debug - start_clock_for_debug) / CLOCKS_PER_SEC << "s" << endl;
            cout << "--------------------------------------------------" << endl;
        }
    #else
        solve();
    #endif
        return 0;
    }
    
  • 相关阅读:
    (转)Lucene.net搜索结果排序(单条件和多条件)
    .Net去html标签
    (转)Lucene.Net多字段查询,多索引查询
    HttpUtility
    内存卡问题汇总
    我的NHibernate
    (转)lucene.net和(pangu)盘古分词 搜索引擎的简单实现
    Power Designer使用技巧
    Oracle添加修改删除表字段
    在数据库开发过程中,数据库、表、字段、视图、存储过程等的命名规则
  • 原文地址:https://www.cnblogs.com/mauve-hkq/p/13336520.html
Copyright © 2011-2022 走看看