Cod sursa(job #469196)

Utilizator S7012MYPetru Trimbitas S7012MY Data 6 iulie 2010 20:52:07
Problema Componente biconexe Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.34 kb
#include <cstdio>
#include <stack>
using namespace std;
#define DN 100005
#define DM DN*(DN-1)/2

int n,dfn[DN],//NUMARUL DE ORDINE A LUI X IN PARCURGEREA DFS A GRAFULUI
    low[DN],/*NUMARUL DE ORDINE AL PRIMULUI VARF DIN PARCURGEREA DFS CE POATE FI ATINS DIN X PE UN ALT
             *LANT DECAT LANTUL UNIC DIN ARBORELE PARTIAL DFS
             *low[x]=min(dfn[x],min(low[y]|y fiu a lui x))
             */
    nrfii,//numarul fiilor  varfului de start in arborele partial dfs
    start=3,nr,varf,
    num;//numarul de ordine al varfului curent in parcurgerea in adancime
 //utilizam o stiva in care punem muchiile din graf in ordinea parcurgerii.
//cand identificam o comp biconexa eliminam din stiva toate muchiile din acea componenta

struct stiva {int f,t;} s[9999999];
struct nod {
    int x;
    nod *urm;
} *v[DN];

void adaugare (int x,int y) {
    nod *p;
    p=new nod;
    p->x=y;
    p->urm=v[x];
    v[x]=p;
}

void afiscompb(int x,int u) {
    stiva p;
    do {
        p=s[varf--];
       // printf(" %d %d",p.t,p.f);
    } while(p.t!=u || p.f!=x);
    //printf("\n");
}

void biconex(int u,int tu) {//u este nodul curent, tu arintele lui
    nod *p;
    dfn[u]=low[u]=++num;
    for(p=v[u]; p!=NULL; p=p->urm) {//urmasii
        if(p->x!=tu && dfn[p->x]<dfn[u])//adaugam in stiva muchia ux
            s[++varf].f=p->x;
            s[varf].t=u;
        if(dfn[p->x]==-1) {//nu a mai fost vizitat
            if(u==start)//am gasit un fiu al nodului start
                ++nrfii;
            biconex(p->x,u);
            low[u]=min(low[u],low[p->x]);
            if(low[p->x]>=dfn[u]) //u e punct de articulatie
                                   //am identificat o comp biconexa formata din muchiile din stiva pana la ux
                if(u!=start) {
                    ++nr;
                    afiscompb(p->x,u);
                }
        }
        else //a mai fost vizitat
            if(p->x!=tu) //x nu e tatal lui u => u x estemuchie de intoarcere de la u la x
                low[u]=min(low[u],dfn[p->x]);
    }
}

int main()
{
    int x,y,m,i;
	freopen("biconex.in","r",stdin);
	freopen("biconex.out","w",stdout);
	scanf("%d %d",&n,&m );
	for(i=1; i<=m; i++) {
	    scanf("%d %d",&x,&y );
	    adaugare(x,y);
	    adaugare(y,x);
	}
	for(i=1; i<=n; i++) dfn[i]=low[i]=-1;
	s[0].f=start;
	s[0].t=-1;
	varf=0;
	biconex(start,-1);
	printf("%d",nr);
	return 0;
}