답안 #251412

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
251412 2020-07-21T07:20:44 Z Sorting Pipes (CEOI15_pipes) C++14
70 / 100
4446 ms 65536 KB
#include <bits/stdc++.h>

using namespace std;

const int k_M = 6e6 + 3;
const int k_N = 1e5 + 3;
const int k_LOG_N = 20;

int n, m;
vector<int> adj[k_N];

vector<pair<int, int>> edges;

int p[k_N], sz[k_N], root[k_N], suffix[k_N];
int up[k_LOG_N][k_N], d[k_N];

bitset<k_N> not_critical;

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

int dfs(int x, int parent = -1){
    int sum = 0;
    for(const int &idx: adj[x]){
        int to = (edges[idx].first == x) ? edges[idx].second : edges[idx].first;
        if(to == parent) continue;

        int curr = dfs(to, x);
        if(curr) not_critical[idx] = true;
        sum += curr;
    }

    return sum += suffix[x];
}

void dfs_join(int x, int parent){
    up[0][x] = parent;
    d[x] = d[parent] + 1;

    for(int i = 1; i < k_LOG_N; ++i)
        up[i][x] = up[i - 1][up[i - 1][x]];

    for(const int &idx: adj[x]){
        int to = (edges[idx].first == x) ? edges[idx].second : edges[idx].first;
        if(to == parent) continue;
        dfs_join(to, x);
    }
}

bool unite(int x, int y){
    if(find_p(x) == find_p(y)) return false;
    if(sz[p[x]] < sz[p[y]]) swap(x, y);

    dfs(root[p[y]]);
    dfs_join(y, x);

    sz[p[x]] += sz[p[y]];
    p[p[y]] = p[x];
    return true;
}

int get_lca(int u, int v){
    if(d[u] < d[v]) swap(u, v);

    int diff = d[u] - d[v];
    if(diff){
        for(int i = k_LOG_N - 1; i >= 0; --i){
            if(diff & (1 << i)){
                u = up[i][u];
            }
        }
    }

    if(u == v) return u;

    for(int i = k_LOG_N - 1; i >= 0; --i){
        if(up[i][u] != up[i][v]){
            u = up[i][u];
            v = up[i][v];
        }
    }

    return up[0][u];
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    
    //cout << (sizeof(up) + sizeof(p) + sizeof(sz) + sizeof(suffix) + sizeof(root) + sizeof(not_critical) + sizeof(adj) + sizeof(edges) + 4 * sizeof(int) * k_N + 7 * sizeof(int) * k_N) / 1024 / 1024 << endl;

    cin >> n >> m;

    for(int i = 1; i <= n; ++i){
        p[i] = i;
        sz[i] = 1;
        root[i] = i;
        suffix[i] = 0;
        d[i] = 0;

        //for(int j = 0; j < k_LOG_N; ++j)
        //    up[j][i] = i;
    }

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

        if(unite(u, v)){
            edges.push_back({u, v});
            adj[u].push_back(edges.size() - 1);
            adj[v].push_back(edges.size() - 1);
        }
        else{
            int lca = get_lca(u, v);
            suffix[lca] -= 2;
            suffix[u]++;
            suffix[v]++;
        }
    }

    for(int i = 1; i <= n; ++i)
        if(i == find_p(i))
            dfs(root[i]);

    for(int i = 0; i < edges.size(); ++i)
        if(!not_critical[i])
            cout << edges[i].first << " " << edges[i].second << "\n";
}

Compilation message

pipes.cpp: In function 'int main()':
pipes.cpp:128:22: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for(int i = 0; i < edges.size(); ++i)
                    ~~^~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 2816 KB Output is correct
2 Correct 2 ms 2816 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 8 ms 3456 KB Output is correct
2 Correct 7 ms 3456 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 190 ms 3328 KB Output is correct
2 Correct 195 ms 3328 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 355 ms 4216 KB Output is correct
2 Correct 390 ms 4140 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 601 ms 6100 KB Output is correct
2 Correct 511 ms 6900 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1194 ms 12784 KB Output is correct
2 Correct 1315 ms 12700 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2040 ms 13932 KB Output is correct
2 Correct 1748 ms 13936 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Runtime error 3202 ms 16400 KB Memory limit exceeded
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 3950 ms 16364 KB Output is correct
2 Runtime error 4145 ms 65536 KB Memory limit exceeded
# 결과 실행 시간 메모리 Grader output
1 Correct 4446 ms 15712 KB Output is correct
2 Runtime error 4077 ms 18400 KB Memory limit exceeded