13672022-06-01 19:34:26Valaki2Hálózatjavításcpp14Accepted 50/508ms7488 KiB
#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define pii pair<int, int>
#define mp make_pair
#define fi first
#define se second

/*#define cin inp
ifstream inp("in6.txt");
ifstream corr("out6.txt");*/

const int maxn = 1e4;
const int maxm = 3e5;
const int inf = 1e7 + 42;

int n, m;
vector<int> g[maxn + 1];
vector<pii > ans;

bool vis0[maxn + 1];
bool done0[maxn + 1];
int S, T, F, A;

void dfs0(int x) {
    vis0[x] = true;
    for(int y : g[x]) {
        if(!vis0[y]) {
            dfs0(y);
        } else if(!done0[y]) {
            S = y;
        }
    }
    done0[x] = true;
}

void GetS() {
    for(int i = 1; i <= n; i++) {
        if(!vis0[i]) {
            dfs0(i);
        }
    }
}

int par[maxn + 1];
bool vis1[maxn + 1];
bool done1[maxn + 1];
int timer, low_d, high_d, backedge_cnt, leaf_cnt;
int d[maxn + 1];
int by_d[maxn + 1];
pii special_edge;
bool leaf[maxn + 1];

void dfs1(int x, int p) {
    timer++;
    d[x] = timer;
    vis1[x] = true;
    par[x] = p;
    for(int y : g[x]) {
        if(!vis1[y]) {
            // gyerek
            dfs1(y, x);
        } else if(!done1[y]) {
            // vissza-el
            if(!leaf[x]) {
                leaf_cnt++;
            }
            leaf[x] = true;
            low_d = min(low_d, d[y]);
            high_d = max(high_d, d[y]);
            backedge_cnt++;
            special_edge = mp(x, y);
        } else {
            // kereszt-el vagy elore-el
            //
        }
    }
    done1[x] = true;
}

void GetTF() {
    low_d = inf;
    high_d = 0;
    dfs1(S, -1);
    if(backedge_cnt == 1) {
        ans.pb(special_edge); // edge case 1
    }
    for(int i = 1; i <= n; i++) {
        if(d[i] == low_d) {
            T = i;
        }
        if(d[i] == high_d) {
            F = i;
        }
    }
    for(int i = 1; i <= n; i++) {
        by_d[d[i]] = i;
    }
}

bool vis2[maxn + 1];

int dfs2(int x) {
    vis2[x] = true;
    int res = leaf[x];
    for(int y : g[x]) {
        if(!vis2[y]) {
            res += dfs2(y);
        }
    }
    if(res == leaf_cnt && !A) {
        A = x;
    }
    return res;
}

void GetA() {
    dfs2(S);
}

bool on_path[maxn + 1];
vector<int> path;

void GetPath1() {
    int x = A;
    while(x != F) {
        on_path[x] = true;
        x = par[x];
    }
    on_path[x] = true;
    reverse(path.begin(), path.end());
}

void GetPath2() {
    int x = A;
    while(x != T) {
        path.pb(x);
        x = par[x];
    }
    path.pb(x);
    reverse(path.begin(), path.end());
}

int f[maxn + 1];
bool vis3[maxn + 1];

void dfs3(int x, int val) {
    vis3[x] = true;
    f[x] = val;
    for(int y : g[x]) {
        if(!vis3[y] && !(par[y] == x && on_path[x] && on_path[y])) {
            dfs3(y, val);
        }
    }
}

void CalcF() {
    for(int i = 1; i <= n; i++) {
        f[i] = inf;
    }
    for(int x : path) {
        if(!vis3[x]) {
            dfs3(x, d[x]);
        }
    }
}

vector<int> top;
bool vis4[maxn + 1];

void dfs4(int x) {
    vis4[x] = true;
    for(int y : g[x]) {
        if(!vis4[y] && par[y] == x) {
            dfs4(y);
        }
    }
    top.pb(x);
}

void CalcTop() {
    dfs4(F);
}

bool go[maxn + 1];

void GoBack() {
    for(int x : top) {
        if(x == F || (!leaf[x] && !go[x])) {
            continue;
        }
        if(f[x] != inf && by_d[f[x]] == x && on_path[x] && on_path[par[x]]) {
            ans.pb(mp(par[x], x));
        }
        f[par[x]] = min(f[par[x]], f[x]);
        go[par[x]] = true;
    }
}

void Answer() {
    cout << (int) ans.size() << "\n";
    for(pii p : ans) {
        cout << p.fi << " " << p.se << "\n";
    }
}

void solve() {
    cin >> n >> m;
    for(int i = 0; i < m; i++) {
        int a, b;
        cin >> a >> b;
        g[a].pb(b);
    }
    GetS();
    GetTF();
    GetA();
    GetPath1();
    GetPath2();
    CalcF();
    CalcTop();
    GoBack();
    //
    Answer();
}

bool benne(vector<pii > v, pii p) {
    for(pii q : v) {
        if(p == q) {
            return true;
        }
    }
    return false;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    solve();
    /*int tmp;
    corr >> tmp;
    vector<pii > v(tmp);
    for(pii &p : v) {
        corr >> p.fi >> p.se;
    }
    cout << "Joban benne de nem irom ki:\n";
    for(pii p : v) {
        if(!benne(ans, p)) {
            cout << p.fi << " " << p.se << "\n";
        }
    }
    cout << "Kiirom de nem kellene:\n";
    for(pii p : ans) {
        if(!benne(v, p)) {
            cout << p.fi << " " << p.se << "\n";
        }
    }*/
    /*cout << (int) v.size() << "\n";
    for(int i = 0; i < tmp; i++) {
        cout << v[i].fi << " " << v[i].se << "\n";
    }*/
    return 0;
}

/*
Edge case-ek:
 [X] csak egy visszaél van
 - ...
*/
SubtaskSumTestVerdictTimeMemory
base50/50
1Accepted0/02ms2368 KiB
2Accepted0/08ms5028 KiB
3Accepted1/12ms2668 KiB
4Accepted1/12ms2664 KiB
5Accepted1/11ms2668 KiB
6Accepted1/12ms2968 KiB
7Accepted1/12ms2968 KiB
8Accepted2/23ms3200 KiB
9Accepted2/23ms3232 KiB
10Accepted2/22ms3036 KiB
11Accepted2/23ms3712 KiB
12Accepted2/22ms3128 KiB
13Accepted2/24ms4336 KiB
14Accepted2/24ms4144 KiB
15Accepted2/26ms4684 KiB
16Accepted2/24ms4632 KiB
17Accepted2/26ms5220 KiB
18Accepted2/28ms5900 KiB
19Accepted2/27ms5772 KiB
20Accepted2/28ms6208 KiB
21Accepted2/28ms6444 KiB
22Accepted2/28ms6524 KiB
23Accepted3/38ms6804 KiB
24Accepted4/48ms6956 KiB
25Accepted4/48ms7128 KiB
26Accepted4/48ms7488 KiB