답안 #249167

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
249167 2020-07-14T12:54:14 Z Sorting One-Way Streets (CEOI17_oneway) C++14
100 / 100
292 ms 45304 KB
#include <bits/stdc++.h>

using namespace std;

const int k_N = 1e5 + 3;

struct DisjointSetUnion{
    int p[k_N], sz[k_N];

    DisjointSetUnion(){}

    void resize(int n){
        for(int i = 1; i <= n; ++i){
            p[i] = i;
            sz[i] = 1;
        }
    }

    int get_p(int x){
        if(p[x] == x) return x;
        return p[x] = get_p(p[x]);
    }

    bool unite(int u, int v){
        if(get_p(u) == get_p(v))
            return false;

        if(sz[p[u]] < sz[p[v]])
            swap(u, v);
        sz[p[u]] += sz[p[v]];
        p[p[v]] = p[u];

        return true;
    }
};

int n, m, p;
vector<pair<int, int>> adjacent[k_N];
pair<int, int> edges[k_N];

bool used[k_N];
int depth[k_N];
char ans[k_N];

DisjointSetUnion dsu;
vector<int> adj_dsu[k_N], adj2[k_N];
vector<pair<int, bool>> ve[k_N];

int lca[20][k_N], lca_par[k_N];

void dfs_lca(int node){
    used[node] = true;
    for(int to: adj2[node]){
        if(to == lca_par[node])
            continue;

        lca_par[to] = node;
        depth[to] = depth[node] + 1;
        dfs_lca(to);
    }
}

void init_lca(){
    for(int i = 1; i <= n; ++i) used[i] = false;

    for(int i = 1; i <= n; ++i){
        int x = dsu.get_p(i);
        if(!used[x]){
            depth[x] = 0;
            lca_par[x] = x;
            dfs_lca(x);
        }
    }

    for(int j = 1; j <= n; ++j)
        lca[0][j] = lca_par[j];

    for(int i = 1; i < 20; ++i)
        for(int j = 1; j <= n; ++j)
            lca[i][j] = lca[i - 1][lca[i - 1][j]];
}

int get_lca(int u, int v){
    if(depth[u] < depth[v])
        swap(u, v);
    int diff = depth[u] - depth[v];
    for(int i = 19; i >= 0; --i)
        if(diff & (1 << i))
            u = lca[i][u];

    if(u == v) return u;

    for(int i = 19; i >= 0; --i){
        if(lca[i][u] != lca[i][v]){
            u = lca[i][u];
            v = lca[i][v];
        }
    }
    return lca[0][u];
}

int cycle(int node, int p_idx){
    used[node] = true;

    int ret = node;
    for(auto [to, idx]: adjacent[node]){
        if(idx == p_idx)
            continue;
        if(used[to]){
            ans[idx] = 'B';
            if(depth[to] < depth[ret]) ret = to;
        }
        else{
            depth[to] = depth[node] + 1;
            int x = cycle(to, idx);
            if(x != to) ans[idx] = 'B';
            if(depth[x] < depth[ret]) ret = x;
        }
    }

    return ret;
}

pair<int, bool> dfs(int node){
    //cout << "dfs " << node << "\n";
    used[node] = true;

    pair<int, bool> ret{node, false};
    for(int idx: adj_dsu[node]){
        int to;
        if(dsu.get_p(edges[idx].first) == node) to = dsu.get_p(edges[idx].second);
        else to = dsu.get_p(edges[idx].first);

        if(used[to])
            continue;

        depth[to] = depth[node] + 1;
        pair<int, bool> curr = dfs(to);
        if(depth[curr.first] <= depth[node]) ans[idx] = (curr.second ^ (dsu.get_p(edges[idx].first) == node)) ? 'R' : 'L';
        if(depth[curr.first] < depth[ret.first]) ret = curr;
    }

    for(auto p: ve[node]){
        if(depth[p.first] == -1) continue;
        //cout << node << " nodenonde " << p.first << " " << p.second << "\n";
        if(depth[p.first] < depth[ret.first]) ret = p;
    }

    //cout << "return " << node << " - " << ret.first << " " << ret.second << "\n";
    return ret;
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    cin >> n >> m;
    for(int i = 0; i < m; ++i){
        int u, v;
        cin >> u >> v;

        adjacent[u].push_back({v, i});
        adjacent[v].push_back({u, i});
        ans[i] = 'U';
        edges[i] = {u, v};
    }

    for(int i = 1; i <= n; ++i){
        if(!used[i]){
            depth[i] = 0;
            cycle(i, -1);
        }
    }

    dsu.resize(n);
    for(int i = 0; i < m; ++i)
        if(ans[i] == 'B')
            dsu.unite(edges[i].first, edges[i].second);

    for(int i = 0; i < m; ++i){
        if(ans[i] == 'U'){
            int pf = dsu.get_p(edges[i].first), ps = dsu.get_p(edges[i].second);
            adj_dsu[pf].push_back(i);
            adj_dsu[ps].push_back(i);

            adj2[pf].push_back(ps);
            adj2[ps].push_back(pf);
            //cout << ps << " - " << pf << "\n";
        }
    }

    init_lca();

    cin >> p;
    for(int i = 0; i < p; ++i){
        int u, v;
        cin >> u >> v;

        int pu = dsu.get_p(u), pv = dsu.get_p(v);
        if(pu != pv){
            int lca = get_lca(pu, pv);
            //cout << lca << " " << pu << " " << pv << " lca pu pv\n"; 
            if(lca == pu || lca == pv){
                ve[pu].push_back({pv, true});
                ve[pv].push_back({pu, false});
            }
            else{
                ve[pu].push_back({lca, true});
                ve[pv].push_back({lca, false});
            }
        }
    }

    for(int i = 1; i <= n; ++i){
        used[i] = false;
        depth[i] = -1;
    }

    for(int i = 1; i <= n; ++i){
        int pi = dsu.get_p(i);
        if(!used[pi]){
            depth[pi] = 0;
            dfs(pi);
        }
    }
    
    for(int i = 0; i < m; ++i)
        if(ans[i] == 'U')
            ans[i] = 'B';

    for(int i = 0; i < m; ++i)
        cout << ans[i];
    cout << "\n";
}

Compilation message

oneway.cpp: In function 'int cycle(int, int)':
oneway.cpp:106:14: warning: decomposition declaration only available with -std=c++1z or -std=gnu++1z
     for(auto [to, idx]: adjacent[node]){
              ^
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 9856 KB Output is correct
2 Correct 6 ms 9856 KB Output is correct
3 Correct 6 ms 9984 KB Output is correct
4 Correct 7 ms 10112 KB Output is correct
5 Correct 7 ms 10112 KB Output is correct
6 Correct 6 ms 9984 KB Output is correct
7 Correct 7 ms 10112 KB Output is correct
8 Correct 7 ms 10112 KB Output is correct
9 Correct 6 ms 9984 KB Output is correct
10 Correct 7 ms 9984 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 9856 KB Output is correct
2 Correct 6 ms 9856 KB Output is correct
3 Correct 6 ms 9984 KB Output is correct
4 Correct 7 ms 10112 KB Output is correct
5 Correct 7 ms 10112 KB Output is correct
6 Correct 6 ms 9984 KB Output is correct
7 Correct 7 ms 10112 KB Output is correct
8 Correct 7 ms 10112 KB Output is correct
9 Correct 6 ms 9984 KB Output is correct
10 Correct 7 ms 9984 KB Output is correct
11 Correct 46 ms 17656 KB Output is correct
12 Correct 58 ms 19448 KB Output is correct
13 Correct 70 ms 22264 KB Output is correct
14 Correct 93 ms 26532 KB Output is correct
15 Correct 91 ms 28024 KB Output is correct
16 Correct 147 ms 31540 KB Output is correct
17 Correct 126 ms 34656 KB Output is correct
18 Correct 139 ms 31608 KB Output is correct
19 Correct 115 ms 36856 KB Output is correct
20 Correct 59 ms 20600 KB Output is correct
21 Correct 54 ms 20584 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 9856 KB Output is correct
2 Correct 6 ms 9856 KB Output is correct
3 Correct 6 ms 9984 KB Output is correct
4 Correct 7 ms 10112 KB Output is correct
5 Correct 7 ms 10112 KB Output is correct
6 Correct 6 ms 9984 KB Output is correct
7 Correct 7 ms 10112 KB Output is correct
8 Correct 7 ms 10112 KB Output is correct
9 Correct 6 ms 9984 KB Output is correct
10 Correct 7 ms 9984 KB Output is correct
11 Correct 46 ms 17656 KB Output is correct
12 Correct 58 ms 19448 KB Output is correct
13 Correct 70 ms 22264 KB Output is correct
14 Correct 93 ms 26532 KB Output is correct
15 Correct 91 ms 28024 KB Output is correct
16 Correct 147 ms 31540 KB Output is correct
17 Correct 126 ms 34656 KB Output is correct
18 Correct 139 ms 31608 KB Output is correct
19 Correct 115 ms 36856 KB Output is correct
20 Correct 59 ms 20600 KB Output is correct
21 Correct 54 ms 20584 KB Output is correct
22 Correct 292 ms 39288 KB Output is correct
23 Correct 266 ms 36216 KB Output is correct
24 Correct 262 ms 36216 KB Output is correct
25 Correct 252 ms 45304 KB Output is correct
26 Correct 268 ms 38648 KB Output is correct
27 Correct 245 ms 36216 KB Output is correct
28 Correct 37 ms 14072 KB Output is correct
29 Correct 83 ms 22896 KB Output is correct
30 Correct 87 ms 23572 KB Output is correct
31 Correct 81 ms 22644 KB Output is correct
32 Correct 201 ms 30584 KB Output is correct