Submission #621138

#TimeUsernameProblemLanguageResultExecution timeMemory
621138MKopchevKeys (IOI21_keys)C++17
67 / 100
3065 ms82956 KiB
#include "keys.h"
#include<bits/stdc++.h>
using namespace std;

const int nmax=3e5+42;

vector< pair<int,int> > adj[nmax];

set<int> in[nmax];

int parent[nmax];

int root(int node)
{
    if(parent[node]==node)return node;

    parent[node]=root(parent[node]);

    return parent[node];
}

stack<int> st;

bool been[nmax];

void dfs(int node)
{
    if(been[node])return;

    been[node]=1;

    for(auto w:adj[node])
        if(in[root(node)].count(w.second))
        {
            dfs(w.first);
        }

    st.push(node);
}

vector<int> component={};

void dfs_trav(int node)
{
    if(been[node])return;

    been[node]=1;

    component.push_back(node);

    for(auto w:adj[node])
        if(in[root(w.first)].count(w.second))
        {
            dfs_trav(w.first);
        }
}

void my_merge(int u,int v)
{
    u=root(u);
    v=root(v);

    if(u==v)return;

    if(in[u].size()<in[v].size())swap(u,v);

    for(auto w:in[v])
        in[u].insert(w);

    parent[v]=u;
}

int cnt[nmax];

std::vector<int> find_reachable(std::vector<int> r, std::vector<int> u, std::vector<int> v, std::vector<int> c)
{
    int n=r.size();

    for(int i=0;i<n;i++)
    {
        parent[i]=i;
        in[i].insert(r[i]);
    }

    int m=u.size();

    for(int j=0;j<m;j++)
    {
        adj[u[j]].push_back({v[j],c[j]});
        adj[v[j]].push_back({u[j],c[j]});
    }

    for(int t=0;t<9;t++)
    {
        for(int p=0;p<n;p++)
            been[p]=0;

        for(int i=0;i<n;i++)
            if(been[i]==0)
                dfs(i);

        for(int p=0;p<n;p++)
            been[p]=0;

        while(st.size())
        {
            component={};

            int tp=st.top();

            st.pop();

            dfs_trav(tp);

            /*
            cout<<tp<<" ";

            cout<<"component: ";for(auto w:component)cout<<w<<" ";cout<<endl;
            */

            for(int j=1;j<component.size();j++)
                my_merge(component[j-1],component[j]);
        }

        /*
        for(int j=0;j<n;j++)
            cout<<root(j)<<" ";cout<<endl;
        */
    }

    for(int i=0;i<n;i++)
    {
        //cout<<i<<" -> "<<root(i)<<endl;

        cnt[root(i)]++;
    }

    for(int j=0;j<m;j++)
    {
        if(root(u[j])!=root(v[j]))
        {
            if(in[root(u[j])].count(c[j]))cnt[root(u[j])]=0;
            if(in[root(v[j])].count(c[j]))cnt[root(v[j])]=0;
        }
    }

    int MINI=1e9;

    for(int i=0;i<n;i++)
        if(cnt[i])MINI=min(MINI,cnt[i]);

    vector<int> outp(r.size(),0);

    for(int i=0;i<n;i++)
        if(cnt[root(i)]==MINI)outp[i]=1;

	return outp;
}

/*
int main() {
    int n, m;
    assert(2 == scanf("%d%d", &n, &m));
    std::vector<int> r(n), u(m), v(m), c(m);
    for(int i=0; i<n; i++) {
        assert(1 == scanf("%d", &r[i]));
    }
    for(int i=0; i<m; i++) {
        assert(3 == scanf("%d %d %d", &u[i], &v[i], &c[i]));
    }
    fclose(stdin);

    std::vector<int> ans = find_reachable(r, u, v, c);

    for (int i = 0; i < (int) ans.size(); ++i) {
        if(i) putchar(' ');
        putchar(ans[i]+'0');
    }
    printf("\n");
    return 0;
}
*/

Compilation message (stderr)

keys.cpp: In function 'std::vector<int> find_reachable(std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>)':
keys.cpp:121:26: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  121 |             for(int j=1;j<component.size();j++)
      |                         ~^~~~~~~~~~~~~~~~~
keys.cpp:154:5: warning: this 'for' clause does not guard... [-Wmisleading-indentation]
  154 |     for(int i=0;i<n;i++)
      |     ^~~
keys.cpp:157:2: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'for'
  157 |  return outp;
      |  ^~~~~~
#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...