Submission #1126554

#TimeUsernameProblemLanguageResultExecution timeMemory
1126554DenisovPipes (CEOI15_pipes)C++20
40 / 100
1556 ms57948 KiB
//#pragma GCC optimize("Ofast", "unroll-loops")
//#pragma GCC target("sse", "sse2", "sse3", "ssse3", "sse4")

#include <bits/stdc++.h>

#define all(a) a.begin(),a.end()
#define len(a) (int)(a.size())
#define mp make_pair
#define pb push_back
#define fir first
#define sec second
#define fi first
#define se second

using namespace std;

typedef pair<int, int> pii;
typedef long long ll;
typedef long double ld;

template<typename T>
bool umin(T &a, T b) {
    if (b < a) {
        a = b;
        return true;
    }
    return false;
}
template<typename T>
bool umax(T &a, T b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}

#ifdef KIVI
#define DEBUG for (bool _FLAG = true; _FLAG; _FLAG = false)
#define LOG(...) print(#__VA_ARGS__" ::", __VA_ARGS__) << endl
template <class ...Ts> auto &print(Ts ...ts) { return ((cerr << ts << " "), ...); }
#else
#define DEBUG while (false)
#define LOG(...)
#endif

const int max_n = 1e5 + 11, inf = 1000111222;

struct dsu {
public:
    int n;
    vector <int> p, cnt;

    inline void make_set (int v) {
        p[v] = v;
    }

    dsu (int n) : n(n) {
        p.resize(n);
        cnt.assign(n, 1);
        for (int i = 0; i < n; i++) {
            make_set(i);
        }
    }

    inline int get (int v) {
        if (p[v] == v) return v;
        return p[v] = get(p[v]); /// compressing path
    }

    inline bool unite (int a, int b) {
        a = get(a);
        b = get(b);
        if (a == b) return false;
        if (cnt[a] > cnt[b]) {
            swap(a, b);
        }
        p[a] = b;
        cnt[b] += cnt[a];
        return true;
    }
};


const int max_m = 6e6 + 11;

int a[max_m], b[max_m];

vector <int> edge[max_n];


const int L = 10;

int up[max_n][L + 1];

int timer = 0;
int tin[max_n], tout[max_n];
bool used[max_n];

inline void dfs_lca (int v, int p = -1) {
    tin[v] = timer++;
    used[v] = 1;
    up[v][0] = p == -1 ? v : p;
    for (int i = 1; i <= L; i++) {
        up[v][i] = up[up[v][i - 1]][i - 1];
    }
    for (int to : edge[v]) {
        if (to == p) continue;
        dfs_lca(to, v);
    }
    tout[v] = timer;
}

inline bool upper (int a, int b) {
    return tin[a] <= tin[b] && tout[b] <= tout[a];
}

inline int lca (int a, int b) {
    if (upper(a, b)) return a;
    if (upper(b, a)) return b;
    for (int i = L; i >= 0; i--) {
        while (!upper(up[a][i], b)) {
            a = up[a][i];
        }
    }
    return up[a][0];
}

int down[max_n];

inline void go (int v, int p = -1) {
    used[v] = false;
    for (int to : edge[v]) {
        if (to == p) {
            continue;
        }
        go(to, v);
        if (!down[to]) {
            cout << v + 1 << ' ' << to + 1 << '\n';
        }
        down[v] += down[to];
    }
//    if (down[v]) {
//        cout << p + 1 << ' ' << v + 1 << '\n';
//    }
}

int main() {
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);

    ios_base::sync_with_stdio(0);
    cin.tie(0);

    int n, m;
    cin >> n >> m;
    dsu t(n);
    int num = 0;
    for (int i = 0, u, v; i < m; i++) {
        cin >> u >> v;
        --u, --v;
        if (t.unite(u, v)) {
            edge[u].pb(v);
            edge[v].pb(u);
        }
        else {
            a[num] = u;
            b[num] = v;
            ++num;
        }
    }
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs_lca(i);
        }
    }
    for (int i = 0; i < num; i++) {
        int v = lca(a[i], b[i]);
        ++down[a[i]];
        ++down[b[i]];
        down[v] -= 2;
    }
    for (int i = 0; i < n; i++) {
        if (used[i]) {
            go(i);
        }
    }
}
#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...
#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...