제출 #813936

#제출 시각아이디문제언어결과실행 시간메모리
813936becaidoKeys (IOI21_keys)C++17
9 / 100
526 ms63908 KiB
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx,popcnt,sse4,abm")
#include <bits/stdc++.h>
using namespace std;
 
#ifndef WAIMAI
#include "keys.h"
#endif
 
#ifdef WAIMAI
#define debug(HEHE...) cout << "[" << #HEHE << "] : ", dout(HEHE)
void dout() {cout << '\n';}
template<typename T, typename...U>
void dout(T t, U...u) {cout << t << (sizeof...(u) ? ", " : ""), dout(u...);}
#else
#define debug(...) 7122
#endif
 
#define ll long long
#define Waimai ios::sync_with_stdio(false), cin.tie(0)
#define FOR(x,a,b) for (int x = a, I = b; x <= I; x++)
#define pb emplace_back
#define F first
#define S second
 
const int SIZE = 3e5 + 5;
 
int n, m;
int a[SIZE];
vector<int> adj[SIZE];
int tot[SIZE], deg[SIZE];
array<int, 4> e[2 * SIZE];
 
struct SCC { // need adj
    int n, dfcnt = 0, sccnt = 0;
    vector<int> dfn, low, scc, st, ist;
    vector<vector<int>> scc_adj;
    SCC() {}
    SCC(int n) : n(n) {
        dfn = low = scc = ist = vector<int>(n + 1, 0);
        scc_adj = vector<vector<int>>(n + 1, vector<int>());
    }
    void tarjan(int pos) {
        dfn[pos] = low[pos] = ++dfcnt;
        st.emplace_back(pos);
        ist[pos] = 1;
        for (int np : adj[pos]) {
            if (dfn[np] == 0) {
                tarjan(np);
                low[pos] = min(low[pos], low[np]);
            } else if (ist[np] == 1) {
                low[pos] = min(low[pos], dfn[np]);
            }
        }
        if (dfn[pos] == low[pos]) {
            sccnt++;
            while (1) {
                int x = st.back();
                ist[x] = 0;
                scc[x] = sccnt;
                st.pop_back();
                if (x == pos) {
                    break;
                }
            }
        }
    }
    void work() {
        for (int i = 1; i <= n; i++) {
            if (dfn[i] == 0) {
                tarjan(i);
            }
        }
    }
    void build_adj() {
        for (int i = 1; i <= n; i++) {
            for (int j : adj[i]) {
                if (scc[i] != scc[j]) {
                    scc_adj[scc[i]].emplace_back(scc[j]);
                }
            }
        }
    }
};
 
vector<int> find_reachable(vector<int> r, vector<int> u, vector<int> v, vector<int> c) {
    n = r.size();
    m = u.size();
    SCC g(n);
    FOR (i, 0, n - 1) a[i + 1] = r[i] + 1;
    FOR (i, 0, m - 1) {
        e[2 * i + 1] = {u[i] + 1, v[i] + 1, c[i] + 1, 0};
        e[2 * i + 2] = {v[i] + 1, u[i] + 1, c[i] + 1, 0};
    }
    m <<= 1;
    int mx = *max_element(a + 1, a + n + 1);
    g.work();
    FOR (color, 1, mx) {
        int sz = g.sccnt;
        vector<int> is(sz + 1);
        FOR (i, 1, n) if (a[i] == color) is[g.scc[i]] = 1;
        FOR (i, 1, m) {
            auto &[a, b, c, vs] = e[i];
            if (vs) continue;
            if (c == color && is[g.scc[a]]) adj[a].pb(b), vs = 1;
        }
        SCC tmp(n);
        tmp.work();
        g = tmp;
    }
    int sz = g.sccnt;
    FOR (i, 1, n) tot[g.scc[i]]++;
    FOR (i, 1, n) for (int j : adj[i]) if (g.scc[i] != g.scc[j]) deg[g.scc[i]]++;
    unordered_set<int> ans;
    int mn = n + 1;
    FOR (i, 1, sz) if (deg[i] == 0) {
        if (tot[i] < mn) {
            mn = tot[i];
            unordered_set<int> emp;
            swap(emp, ans);
        }
        if (tot[i] == mn) ans.insert(i);
    }
    vector<int> all(n);
    FOR (i, 1, n) if (ans.count(g.scc[i])) all[i - 1] = 1;
    return all;
}
 
/*
in1
4 5
0 1 1 2
0 1 0
0 2 0
1 2 1
1 3 0
3 1 2
out1
0 1 1 0
 
in2
7 10
0 1 1 2 2 1 2
0 1 0
0 2 0
1 2 1
1 3 0
2 3 0
3 4 1
3 5 2
4 5 0
4 6 2
5 6 1
out2
0 1 1 0 1 0 1
 
in3
3 1
0 0 0
0 1 0
out3
0 0 1
*/
 
#ifdef WAIMAI
int main() {
    int n, m;
    assert(2 == scanf("%d%d", &n, &m));
    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);
 
    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;
}
#endif
#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...