Pagini recente » Cod sursa (job #334337) | Cod sursa (job #1962647) | Cod sursa (job #1323968) | Cod sursa (job #1293295) | Cod sursa (job #2945948)
#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);
}
}
}