Cod sursa(job #2153202)

Utilizator amaliarebAmalia Rebegea amaliareb Data 6 martie 2018 00:48:14
Problema Componente tare conexe Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.49 kb
#include <bits/stdc++.h>

using namespace std;
ifstream f("ctc.in");
ofstream g("ctc.out");
const int MaxN = 100005;
int n, m;
int onst[MaxN], low[MaxN], val[MaxN], unde[MaxN], poz[MaxN], nr, tata[MaxN], aint[4 * MaxN], bef[MaxN], ans, d[MaxN];
bitset<MaxN> viz;
vector<int> gr[MaxN], tati[MaxN];
stack<int> st;
vector<vector<int> > comps;

void Ctc(int node) {
    viz[node] = 1;
    st.push(node);
    onst[node] = st.size();
    low[node] = onst[node];
    for (auto son: gr[node]) {
        if (!viz[son]) {
            Ctc(son);
            low[node] = min(low[node], low[son]);
        }
        else if (onst[son]) low[node] = min(low[node], onst[son]);
    }
    if (low[node] == onst[node]) {
        vector<int> v;
        while (st.top() != node) {
            v.push_back(st.top());
            onst[st.top()] = 0;
            st.pop();
        }
        st.pop();
        v.push_back(node);
        onst[node] = 0;
        sort(v.begin(), v.end());
        for (auto x: v) unde[x] = v[0];
        comps.push_back(v);
    }
}

void Sortare(int node) {
    viz[node] = 1;
    for (auto son: gr[node]) {
        if (!viz[son]) Sortare(son);
    }
    poz[node] = ++nr;
}

void Update(int node, int l, int r, int poz, int val) {
    if (l == r) {
        aint[node] = val;
        return;
    }
    int mid = (l + r) / 2;
    if (poz <= mid) Update(2 * node, l, mid, poz, val);
    else Update(2 * node + 1, mid + 1, r, poz, val);
    aint[node] = max(aint[2 * node], aint[2 * node + 1]);
}

int Query(int node, int l, int r, int ql, int qr) {
    if (l >= ql && r <= qr) return aint[node];
    int mid = (l + r) / 2;
    int ret = 0;
    if (ql <= mid) ret = max(ret, Query(2 * node, l, mid, ql, qr));
    if (qr > mid) ret = max(ret, Query(2 * node + 1, mid + 1, r, ql, qr));
    return ret;
}

void Dfs(int node) {
    viz[node] = 1;
    bef[node] = Query(1, 1, MaxN, val[node], val[node]);
    if (val[node] > 1) d[node] = Query(1, 1, MaxN, 1, val[node] - 1) + 1;
    else d[node] = 1;
    ans = max(ans, d[node]);
    if (bef[node] < d[node]) Update(1, 1, MaxN, val[node], d[node]);
    for (auto son: gr[node])
        if (!viz[son]) Dfs(son);
    Update(1, 1, MaxN, val[node], bef[node]);
}

int main()
{
    f >> n >> m;
    for (int i = 1; i <= n; ++i) val[i] = 1;
    for (int i = 1; i <= m; ++i) {
        int x, y;
        f >> x >> y;
        gr[x].push_back(y);
    }
    Ctc(1);
    g << comps.size() << '\n';
    for (auto v: comps) {
        for (auto x: v) g << x << ' ';
        g << '\n';
    }
    viz.reset();
    for (auto v: comps) {
        int y = v.back();
        vector<int> my;
        for (auto node: v) {
            for (auto son: gr[node]) {
                if (unde[son] != unde[node]) my.push_back(unde[son]);
            }
            gr[node].clear();
        }
        gr[y].swap(my);
        for (int i = 0; i < v.size() - 1; ++i) gr[v[i]].push_back(v[i + 1]);
    }
    for (int i = 1; i <= n; ++i) {
        for (auto x: gr[i]) tati[x].push_back(i);
    }
    for (int i = 1; i <= n; ++i) if (!tati[i].size()) {
        Sortare(i);
        break;
    }
    for (int i = 1; i <= n; ++i) {
        int pozmin = 1000000;
        for (auto t: tati[i]) if (poz[t] < pozmin) tata[i] = t, pozmin = poz[t];
        gr[i].clear();
    }
    for (int i = 1; i <= n; ++i) gr[tata[i]].push_back(i);
    viz.reset();
    for (int i = 1; i <= n; ++i) if (!tata[i]) Dfs(i);
    //g << ans << '\n';
    return 0;
}