#include <bits/stdc++.h>
using namespace std;
ifstream f;
ofstream g;
class Graf {
int noduri, muchii;
vector< vector<int> > lista;
public:
Graf(int numar_noduri, int numar_muchii, int aux);
Graf(int numar_noduri, int numar_muchii);
void out();
void bfs(int start);
void dfs(vector<bool> &vizitat, int start);
void biconex();
void dfs_biconex(vector<bool> &vizitat, int start, int niv, int &niv_int, vector<int> &nivel, vector<int> &nivel_intoarcere);
};
void Graf :: out ()
{
g << noduri << " " << muchii << endl;
for(int i = 0; i < noduri; i++)
{
g << i << " : ";
for(int j = 0 ; j < lista[i].size(); j++)
g << lista[i][j] << " ";
g << endl;
}
}
Graf :: Graf (int numar_noduri, int numar_muchii, int aux)
{
noduri = numar_noduri;
muchii = numar_muchii;
int nod_1, nod_2;
lista.resize(numar_noduri + 1);
for(int i = 1; i <= numar_muchii; i++)
{
f >> nod_1 >> nod_2;
lista[nod_1].push_back(nod_2);
}
}
Graf :: Graf (int numar_noduri, int numar_muchii)
{
noduri = numar_noduri;
muchii = numar_muchii;
int nod_1, nod_2;
lista.resize(numar_noduri + 1);
for(int i = 1; i <= numar_muchii; i++)
{
f >> nod_1 >> nod_2;
lista[nod_1].push_back(nod_2);
lista[nod_2].push_back(nod_1);
}
}
void Graf :: bfs(int start)
{
int distanta[noduri + 1];
for(int index = 1; index <= noduri; index++)
distanta[index] = -1;
bool vizitat[noduri + 1] = {false};
queue<int> q;
q.push(start);
distanta[start] = 0;
vizitat[start] = true;
while(!q.empty())
{
int nod = q.front();
q.pop();
for(int index = 0; index < lista[nod].size(); index++)
if(vizitat[lista[nod][index]] == false)
{
q.push(lista[nod][index]);
vizitat[lista[nod][index]] = true;
distanta[lista[nod][index]] = distanta[nod] + 1;
}
}
for(int secondIndex = 1; secondIndex <= noduri; secondIndex++)
g << distanta[secondIndex] << " ";
}
void Graf :: dfs(vector<bool> &vizitat, int start)
{
vizitat[start] = true;
for(int index = 0; index < lista[start].size(); index++)
if(vizitat[lista[start][index]] == false)
dfs(vizitat, lista[start][index]);
}
void Graf :: biconex()
{
vector<bool> vizitat;
vizitat.resize(noduri + 1);
vector<int> nivel;
vector<int> nivel_intoarcere;
nivel.resize(noduri + 1);
nivel_intoarcere.resize(noduri + 1);
for(int index = 1; index <= noduri; index++)
{
nivel[index] = 0;
nivel_intoarcere[index] = 0;
}
for(int index = 1; index <= noduri; index++)
vizitat[index] = false;
for(int index = 1; index <= noduri; index++)
{
if(vizitat[index] == false)
{
int niv1 = 0;
dfs_biconex(vizitat, index, 1, niv1, nivel, nivel_intoarcere);
}
}
int contor = 0;
for(int index = 1; index <= noduri; index++)
{
for(int secondIndex = 0; secondIndex < lista[index].size(); secondIndex++)
if(nivel[index] < nivel_intoarcere[lista[index][secondIndex]])
{
contor++;
}
}
g << contor / 2;
}
void Graf :: dfs_biconex(vector<bool> &vizitat, int start, int niv, int &niv_int, vector<int> &nivel, vector<int> &nivel_intoarcere)
{
vizitat[start] = true;
nivel[start] = niv;
for(int index = 0; index < lista[start].size(); index++)
if(vizitat[lista[start][index]] == false)
{
dfs_biconex(vizitat, lista[start][index], niv + 1, niv_int, nivel, nivel_intoarcere);
niv_int++;
nivel_intoarcere[lista[start][index]] = niv_int;
}
}
int main()
{
int problema = 3;
if(problema == 1)
{
f.open ("bfs.in", std::ifstream::in);
g.open ("bfs.out", std::ifstream::out);
int n, m, s;
f >> n >> m >> s;
Graf graf(n, m, s);
graf.bfs(s);
f.close();
g.close();
}
if(problema == 2)
{
int n, m;
f.open ("dfs.in", std::ifstream::in);
g.open ("dfs.out", std::ifstream::out);
f >> n >> m;
vector<bool> vizitat;
vizitat.resize(n + 1);
for(int index = 1; index <= n; index++)
vizitat[index] = false;
Graf graf(n, m);
int contor = 0;
for(int index = 1; index <= n; index++)
{
if(vizitat[index] == false)
{
graf.dfs(vizitat, index);
contor++;
}
}
g << contor;
f.close();
g.close();
}
if(problema == 3)
{
int n, m;
f.open ("biconex.in", std::ifstream::in);
g.open ("biconex.out", std::ifstream::out);
f >> n >> m;
Graf graf(n, m);
graf.biconex();
f.close();
g.close();
}
return 0;
}