답안 #106593

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
106593 2019-04-19T07:06:23 Z teomrn Pipes (CEOI15_pipes) C++14
100 / 100
1472 ms 8776 KB
#include <stdio.h>
#include <algorithm>
#include <vector>
#include <numeric>
#include <assert.h>
using namespace std;

const int NMAX = 100010;

struct UF {
    int g[NMAX];
    int tata[NMAX];

    UF() {
        iota(tata, tata + NMAX, 0);
        fill(g, g + NMAX, 1);
    }

    int find(int x) {
        if (tata[tata[x]] != tata[x])
            tata[x] = find(tata[x]);
        return tata[x];
    }

    bool unite1(int & a, int & b) {
        int newa = find(a);
        int newb = find(b);
        if (newa == newb)
            return 0;

        if (g[newa] < g[newb])
            swap(a, b), swap(newa, newb);
        g[newa] += g[newb];
        tata[newb] = newa;

        return 1;
    }
    bool unite(int a, int b) {
        a = find(a);
        b = find(b);
        if (a == b)
            return 0;

        if (g[a] < g[b])
            swap(a, b);
        g[a] += g[b];
        tata[b] = a;

        return 1;
    }
} simple, strong;

namespace Tree {
    int h[NMAX];
    int father[NMAX];
    int up[NMAX]; /// ultimul cu care stiu sigur ca m-am unit
    vector <int> adia[NMAX]; /// suma ar trebui sa fie max NMAX :)
    vector <pair <int, int>> single;
    int n;

    int find(int nod) {
        if (up[up[nod]] != up[nod])
            up[nod] = find(up[nod]);
        return up[nod];
    }

    void make_strong(int a, int b) {
        a = find(a);
        b = find(b);
        while (1) {
            if (a == b)
                return;

            if (h[a] < h[b])
                swap(a, b);
            /// acum il unesc pe a cu tatal sau
            assert(strong.find(a) != strong.find(father[a]));
            assert(father[a] != 0);
            strong.unite(a, father[a]);
            up[a] = father[a];
            a = find(a);
        }
    }

    void dfs(int nod, int tata) {
        father[nod] = tata;
        h[nod] = 1 + h[tata];
        up[nod] = (strong.find(nod) == strong.find(tata) ? find(tata) : nod);
        for (auto i : adia[nod])
            if (i != tata)
                dfs(i, nod);
    }

    void add_edge(int a, int b) {
        if (simple.unite1(a, b)) {
            adia[a].push_back(b);
            adia[b].push_back(a);
            dfs(b, a);
        }
        else
            make_strong(a, b);
    }

    void dfs_ans(int nod, int tata) {
        for (auto i : adia[nod]) {
            if (i == tata)
                continue;
            if (strong.find(i) != strong.find(nod))
                single.push_back({ nod, i });
            dfs_ans(i, nod);
        }
    }

    void get_ans() {
        for (int i = 1; i <= n; i++)
            if (father[i] == 0)
                dfs_ans(i, 0);
    }

}

int main()
{
    int n, m, a, b;
    scanf("%d%d", &n, &m);
    Tree::n = n;
    iota(Tree::up, Tree::up + NMAX, 0);

    while (m--) {
        scanf("%d%d", &a, &b);
        Tree::add_edge(a, b);
    }

    Tree::get_ans();

    for (auto i : Tree::single)
        printf("%d %d\n", i.first, i.second);

    return 0;
}

Compilation message

pipes.cpp: In function 'int main()':
pipes.cpp:125:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%d%d", &n, &m);
     ~~~~~^~~~~~~~~~~~~~~~
pipes.cpp:130:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
         scanf("%d%d", &a, &b);
         ~~~~~^~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 5 ms 4580 KB Output is correct
2 Correct 5 ms 4608 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 8 ms 4736 KB Output is correct
2 Correct 8 ms 4836 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 113 ms 4792 KB Output is correct
2 Correct 109 ms 4792 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 201 ms 5120 KB Output is correct
2 Correct 258 ms 4992 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 332 ms 5588 KB Output is correct
2 Correct 285 ms 5752 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 450 ms 7416 KB Output is correct
2 Correct 421 ms 7488 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 699 ms 7832 KB Output is correct
2 Correct 722 ms 7860 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1022 ms 8568 KB Output is correct
2 Correct 905 ms 8696 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1206 ms 8564 KB Output is correct
2 Correct 1245 ms 8616 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1472 ms 8364 KB Output is correct
2 Correct 1393 ms 8776 KB Output is correct