[2020 Niuke Multi-School] 2020 Niuke Summer Multi-School Training Camp (la tercera sesión) G-Operando en un Problema de Violencia Estúpida de Gráficos

G-Operación en un gráfico

Enlace de tema

Significado general

Te doy una foto con nnn puntos,mmm aristas, el subíndice del punto es de0 → n - 1 0 \ rightarrow n-10norte-1
para el puntoiiyo , pertenece ai - grupo i-grupoal principioyo-g r o u p
operaciones totalesqqq veces, dando unnn paracada operaciónn , combinar todo conn - grupo n-gruponorte-g r o u p grupo de grupoconectado directamenteg r o u p se une an - grupo n-gruponorte-En g r o u p , una vez
finalizadas todas las operaciones, busque elgrupo de grupodonde se encuentra cada puntog r o u p

Dirección de pensamiento simple

Usando STLla listconexión, listanalógica queue, y luego hacer con disjoint-set

Ideas específicas

Primero, grupo de grupoG R & lt O U P ............ no es que ............ disjoint-set
excepto que no puede proporcionar un lado de repente traídounitesolo una capaunite(elBFS BFSConsiderando desde la perspectiva de B F S , el significado de esta capa)
entonces puede ser para cadagrupoG R & lt O U P en un guardadoqueue, y luego cada vez que laqueuecapa deBFS BFSB F S

Pero considerando dos grupos de grupoDespués de la unión de g r o u p conduce a uno de losgrupos de grupoG R & lt O U P dequeuedatos que se fusionarán con otro, yqueuela eficiencia combinada es demasiado baja, se utilizalistpara simularqueue, ya quelisthayspliceun método, la eficiencia es muy alta

En segundo lugar, para evitar la duplicación de BFS BFSB F. S , aumentando así lavisitmatriz

Código AC

#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) << " \n"[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;
}

Supongo que te gusta

Origin blog.csdn.net/m0_43448982/article/details/107432046
Recomendado
Clasificación