Cod sursa(job #2945948)

Utilizator Chris_BlackBlaga Cristian Chris_Black Data 24 noiembrie 2022 12:53:39
Problema Componente tare conexe Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.31 kb
#include <fstream>
#include <vector>
#include <stack>
#include <queue>
#include <unordered_set>
using namespace std;
ifstream cin("ctc.in");
ofstream cout("ctc.out");


int n,m,ctc,idx;
vector<int> c,level,low;
vector<vector<int> > cc;
vector<unordered_set<int> > sirad;
stack<int> st;
vector<bool> instk,viz,in,out;
vector<int> apart,reprez;

void Tarjan();
void Dfs();

int main()
{
    int a,b;
    cin>>n>>m;
    sirad = vector<unordered_set<int>>(n+1);
    viz = instk = in = out = vector<bool>(n+1);
    level = low = apart = vector<int>(n+1);
    for(int i=1;i<=m;++i)
    {
        cin>>a>>b;
        if(a!=b)
        {
            sirad[a].insert(b);
        }
    }
    Tarjan();
    reprez = vector<int>(ctc+1);
    for(int i=1;i<=n;++i)
    {
        for(auto j : sirad[i])
        {
            if(apart[i]!=apart[j])
            {
                reprez[apart[i]] = i;
                reprez[apart[j]] = j;
                in[apart[j]] = 1;
                out[apart[i]] = 1;
            }
        }
    }


    queue<int> sink,come;
    for(int i=1;i<=ctc;++i)
    {
        if(in[i]==0)come.push(i);
        if(out[i]==0)sink.push(i);
    }
    cout<<max(come.size(),sink.size())<<'\n';

    while(!come.empty()&&!sink.empty())
    {
        cout<<reprez[sink.front()]<<' '<<reprez[come.front()]<<'\n';
        sink.pop();
        come.pop();
    }
    while(!come.empty())
    {
        cout<<1<<' '<<reprez[come.front()]<<'\n';
        come.pop();
    }
    while(!sink.empty())
    {
        cout<<reprez[sink.front()]<<' '<<1<<'\n';
        sink.pop();
    }
    return 0;
}
void Dfs(int x)
{
    st.push(x);
    instk[x] = 1;
    viz[x] = 1;
    level[x] = low[x] = ++idx;

    for(auto i : sirad[x])
        if(!viz[i])
        {
            Dfs(i);
            low[x] = min(low[x],low[i]);
        }
        else if(instk[i])low[x] = min(low[x],level[i]);

    if(level[x] == low[x])
    {
        ++ctc;
        while(!st.empty())
        {
            int a = st.top();
            st.pop();
            instk[a] = 0;
            apart[a] = ctc;
            if(level[a]==low[a])break;
        }
    }

}

void Tarjan()
{

    for(int i=1;i<=n;++i)
    {
        if(!viz[i])
        {
            Dfs(i);
        }
    }
}