Pagini recente » Cod sursa (job #461781) | Cod sursa (job #1033911) | Cod sursa (job #3149874) | Cod sursa (job #1902286) | Cod sursa (job #1474144)
/*
Fie T un arbore de adâncime descoperit de parcurgerea grafului. Atunci, un nod v este punct de articulaţie dacă:
v este rădăcina lui T şi v are doi sau mai mulţi copii
sau
v nu este rădăcina lui T şi are un copil u în T, astfel încât nici un nod din subarborele dominat
de u nu este conectat cu un strămoş al lui v printr-o muchie înapoi (copii lui nu pot ajunge pe altă
cale pe un nivel superior în arborele de adâncime).
idx[u] = timpul de descoperire a nodului u
low[u] = min( {idx[u]} U { idx[v] : (u, v) este o muchie înapoi } U
{ low[vi] : vi copil al lui v în arborele de adâncime} )
+http://pastebin.com/AjZ1LvXj
+http://www.infoarena.ro/job_detail/236392?action=view-source
*/
#include <fstream>
#include <iostream>
#include <set>
#include <stack>
#include <vector>
#include <algorithm>
#include <bitset>
#define nmax 100015
using namespace std;
int n,m, idx[nmax], componente, low[nmax];
vector <int> v[nmax];
fstream f,g;
struct edge
{
int nod1, nod2;
edge ()
{
nod1 = nod2 = 0;
}
edge ( int x, int y)
{
nod1 = x;
nod2 = y;
}
bool operator = ( edge a)
{
nod1 = a.nod1;
nod2 = a.nod2;
}
};
stack <edge> stiva;
void determina_componenta_biconexa(int x, int y)
{
componente++;
int folosit[nmax] = {0};
edge muchie;
do
{
muchie = stiva.top();
stiva.pop();
if ( !folosit[muchie.nod1] ) g<<muchie.nod1<<" ";
if ( !folosit[muchie.nod2] ) g<<muchie.nod2<<" ";
folosit[muchie.nod1] = 1;
folosit[muchie.nod2] = 1;
}while ( muchie.nod1 != x || muchie.nod2 !=y);
g<<'\n';
}
void DFS(int nod, int tata, int nivel)
{
int i;
idx[nod] = nivel;
low [nod] = nivel;//pe ce nivel e posibil sa ma intorc
for ( i = 0 ; i < v[nod].size() ; i++ )
{
if ( tata == v[nod][i])
continue;
if (idx[v[nod][i]] == 0) // nu am umblat pe la el
{
// bag muchia in arborele dfs
edge muchie = edge(nod, v[nod][i]);
stiva.push( muchie);
DFS(v[nod][i], nod, nivel + 1);
// actualizez
low[nod] = min (low[v[nod][i]], low[nod]);
// vad daca e punct de articulatie
if (low[v[nod][i]] >= idx[nod])
determina_componenta_biconexa(nod, v[nod][i]);
}
else
low[nod] = min (low[nod], low[v[nod][i]]); // posibila muchie intoarcere
}
}
int main(void)
{
int i,x,y;
f.open("biconex.in",ios::in);
g.open("biconex.out",ios::out);
f>>n>>m;
for (i = 1 ; i<= m ;i++)
{
f>>x>>y;
v[x].push_back(y);
v[y].push_back(x);
}
//!! vezi daca e conex sau nu
g<<" \n";
DFS (1, 0, 1);// consider 1 radacina;
g.seekg(0,ios::beg);
g<<componente;
}