Pagini recente » Cod sursa (job #2963580) | Cod sursa (job #1839547) | Cod sursa (job #2470389) | Cod sursa (job #2948971) | Cod sursa (job #1799833)
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
const int NMAX = 255;
const int MMAX = 1500;
int last_index;
int Min[NMAX+5];
int ind[NMAX+5];
bool instack[NMAX+5];
int st[NMAX+5], Size;
int indeg[NMAX+5];
bool a[NMAX+5][NMAX+5];
vector <int> g[NMAX+5];
bool vis[NMAX+5];
vector <int> List;
vector <int> cuplaj[NMAX+5];
int left[NMAX+5], right[NMAX+5];
int Comp[NMAX+5];
vector <int> v[NMAX+5];
int comp;
vector <int> ans[NMAX+5];
void dfs(int nod)
{
ind[nod] = last_index;
Min[nod] = last_index;
instack[nod] = true;
last_index++;
st[Size++] = nod;
for(int i=0; i<v[nod].size(); i++)
{
if(ind[v[nod][i]] == 0)
{
dfs(v[nod][i]);
Min[nod] = min(Min[nod], Min[v[nod][i]]);
}
else if(instack[v[nod][i]])
{
Min[nod] = min(Min[nod], Min[v[nod][i]]);
}
}
if(Min[nod] == ind[nod])
{
int top;
comp++;
do
{
Size--;
top = st[Size];
instack[top] = false;
ans[comp].push_back(top);
}
while(Size>=0 && top!=nod);
}
}
void dfs_cuplaj(int nod)
{
vis[nod] = true;
if(g[nod].size() == 0)
{
List.push_back(nod);
return;
}
for(int i=0; i<g[nod].size(); i++)
if(!vis[g[nod][i]])
{
dfs_cuplaj(g[nod][i]);
}
}
bool pairUp(int node)
{
if(vis[node])return false;
vis[node] = true;
for(int i=0; i<cuplaj[node].size(); i++)
{
int right_node = cuplaj[node][i];
if(left[right_node] == 0 || pairUp(left[right_node]) == true)
{
left[right_node] = node;
right[node] = right_node;
return true;
}
}
return false;
}
int main()
{
freopen("plan.in", "r", stdin);
freopen("plan.out", "w", stdout);
int n, m;
scanf("%d%d", &n, &m);
for(int i=0; i<m; i++)
{
int x, y;
scanf("%d%d", &x, &y);
if(x!=y) v[x].push_back(y);
}
last_index = 1;
for(int i=1; i<=n; i++)
if(ind[i] == 0)
dfs(i);
if(comp == 1)
{
printf("0\n");
return 0;
}
for(int i=1; i<=comp; i++)
{
for(int j=0; j<ans[i].size(); j++)
Comp[ans[i][j]] = i;
}
for(int i=1; i<=n; i++)
for(int j=0; j<v[i].size(); j++)
a[Comp[i]][Comp[v[i][j]]] = true;
for(int i=1; i<=comp; i++)
for(int j=1; j<=comp; j++)
if(i!=j && a[i][j])
{
g[i].push_back(j);
indeg[j]++;
}
int nrleft = 0;
for(int i=1; i<=comp; i++)
if(indeg[i] == 0)
nrleft++;
int nrright = 0;
for(int i=1; i<=comp; i++)
if(g[i].size() == 0)
nrright++;
printf("%d\n", max(nrleft, nrright));
for(int i=1; i<=comp; i++)
if(indeg[i] == 0)
{
memset(vis, 0, sizeof(vis));
List.clear();
dfs_cuplaj(i);
for(int j=0; j<List.size(); j++)
cuplaj[i].push_back(List[j]);
}
bool ok = true;
while(ok)
{
ok = false;
memset(vis, 0, sizeof(vis));
for(int i=1; i<=comp; i++)
if(right[i] == 0 && pairUp(i)) ok = true;
}
int c = -1, japca;
for(int i=1; i<=comp; i++)
if(indeg[i] == 0 && right[i]!=0)
{
if(c!=-1) printf("%d %d\n", ans[c][0], ans[i][0]);
else japca = i;
c = right[i];
}
printf("%d %d\n", ans[c][0], ans[japca][0]);
for(int i=1; i<=comp; i++)
if(indeg[i] == 0 && right[i] == 0)
printf("%d %d\n", ans[japca][0], ans[i][0]);
for(int i=1; i<=comp; i++)
if(g[i].size() == 0 && left[i] == 0)
printf("%d %d\n", ans[i][0], ans[japca][0]);
return 0;
}