제출 #712466

#제출 시각아이디문제언어결과실행 시간메모리
712466danikoynov열쇠 (IOI21_keys)C++17
0 / 100
31 ms52052 KiB
#include <bits/stdc++.h>
#include "keys.h"

using namespace std;


const int maxn = 3e5 + 10;

struct component
{
    unordered_map < int, vector < int > > edges;
    unordered_set < int > keys;
    vector < int > vertices;
    int parent, cnt_ver;
    int index;
};

component cp[maxn];
int n, ver_index[maxn];
vector < pair < int, int > > graph[maxn];
vector < int > ans;

int lead[maxn];

int find_leader(int v)
{
    if (v == lead[v])
        return v;
    return (lead[v] = find_leader(lead[v]));
}
int max_key;
void merge_components(int v, int u)
{
    //cout << "merge " << v << " " << u << endl;
    //cout << find_leader(v) << " is " << find_leader(u) << endl;

    int cnt0 = 0, cnt1 = 0;
    for (int key = 0; key < max_key; key ++)
    {
        cnt0 += cp[v].edges[key].size();
        cnt1 += cp[u].edges[key].size();
    }
    if (cnt0 > cnt1)
    {
        swap(cp[v].edges, cp[u].edges);
    }
    for (int key = 0; key < max_key; key ++)
    {
        for (int ver : cp[v].edges[key])
        {
            ///cout << "from " << v << " to " << u << " " << ver << endl;
            cp[u].edges[key].push_back(ver);
        }
        cp[u].edges[key].clear();
    }


    if (cp[u].keys.size() < cp[v].keys.size())
        swap(cp[u].keys, cp[v].keys);
    for (int key : cp[v].keys)
        cp[u].keys.insert(key);
    cp[v].keys.clear();
    if (cp[v].vertices > cp[u].vertices)
        swap(cp[v].vertices, cp[u].vertices);
    for (int vertex : cp[v].vertices)
        cp[u].vertices.push_back(vertex);
    cp[v].vertices.clear();
    lead[v] = u;
}


int cp_lead[maxn];

int find_cp_leader(int v)
{
    if (v == cp_lead[v])
        return v;
    return (cp_lead[v] = find_cp_leader(cp_lead[v]));
}
vector<int> find_reachable(vector<int> r, vector<int> u, vector<int> v, vector<int> c)
{
    n = r.size();
    ans.resize(n);
    for (int i = 0; i < n; i ++)
    {
        max_key = max(max_key, r[i] + 1);
    }
    for (int i = 0; i < u.size(); i ++)
    {
        graph[u[i]].push_back({v[i], c[i]});
        graph[v[i]].push_back({u[i], c[i]});
    }

    queue < int > q;
    for (int i = 0; i < n; i ++)
    {

        lead[i] = i;
        cp_lead[i] = i;
        cp[i].keys.insert(r[i]);
        for (pair < int, int > nb : graph[i])
        {
            cp[i].edges[nb.second].push_back(nb.first);
        }
        cp[i].parent = -1;
        cp[i].cnt_ver = 1;
        cp[i].vertices.push_back(i);
        cp[i].index = i;
        ver_index[i] = i;
        q.push(i);
    }

    while(!q.empty())
    {
        int cur = q.front();
        q.pop();
        if (cur != find_leader(cur))
            continue;
        ///cout << cur << " :: " << cp[cur].parent << endl;
        for (int key : cp[cur].keys)
        {
            bool done = false;
            while(!cp[cur].edges[key].empty())
            {

                int to = cp[cur].edges[key].back();
                ///cout << "edge " << cur << " " << to << endl;
                to = find_leader(to);

                cp[cur].edges[key].pop_back();
                ///cout << "store " << cur << " " << key << " " << cp[cur].edges[key].back() << endl;
                if (to == cur)
                    continue;
                ///cout << cur << " :: " << to << endl;
                int up = find_cp_leader(to);

                if (up != cur)
                {
                    cp[cur].parent = to;
                    cp_lead[cur] = to;
                    ///to = find_leader(to);
                    //cout << cur << " --- " << up << endl;
                    done = true;
                    break;
                }

                while(to != cur)
                {
                    int to_go = cp[to].parent;
                    to_go = find_leader(to_go);
                    ///cout << to << " compare " << cur << endl;
                    merge_components(to, to_go);
                    to = to_go;
                }
                q.push(cur);
                done = true;
                break;
            }
            if (done)
                break;
        }
    }

    /**for (int key = 0; key < n; key ++)
        for (int ver : cp[4].edges[key])
            cout << ver << " :: " << endl;*/
    int least = n + 1;
    for (int i = 0; i < n; i ++)
    {
        int v = find_leader(i);
        if (cp[v].parent != -1)
            continue;
        least = min(least, (int)cp[v].vertices.size());
    }

    for (int i = 0; i < n; i ++)
    {
        int v = find_leader(i);
        if (cp[v].parent != -1)
            continue;
        if (cp[v].vertices.size() != least)
            continue;
        ///cout << v << " " << cp[v].vertices.size() << endl;
        for (int vertex : cp[v].vertices)
            ans[vertex] = 1;
        cp[v].vertices.clear();
    }

    return ans;
}

컴파일 시 표준 에러 (stderr) 메시지

keys.cpp: In function 'std::vector<int> find_reachable(std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>)':
keys.cpp:88:23: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   88 |     for (int i = 0; i < u.size(); i ++)
      |                     ~~^~~~~~~~~~
keys.cpp:181:35: warning: comparison of integer expressions of different signedness: 'std::vector<int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
  181 |         if (cp[v].vertices.size() != least)
      |             ~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...