Cod sursa(job #1038333)

Utilizator TED_996Budaca Eduard TED_996 Data 21 noiembrie 2013 12:59:40
Problema Componente tare conexe Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 4.03 kb
#include<cstdio>
#define null NULL

using namespace std;

FILE* fout;

struct str_NodLista {
    int info;
    str_NodLista* next;
};

struct str_Lista {
    str_NodLista* first;
    str_NodLista* last;

    str_NodLista* currentNode;
    int currentIndex;

    int size;

    void pushBack(int info);
    int get(int index);
    void init();
};

int nrNoduri;
str_Lista listeAdiacenta[100008];
str_Lista listeTranspuse[100008];

int postOrdine[100008];
int indPostOrdine = 0;

bool used[100008];

int component[100008];
int nrComponente;

void init();
void citire();
void genPostOrdine();
void genComponente();
void afisare();

int main(){
	citire();

    genPostOrdine();
    genComponente();

	afisare();
	return 0;
}

void init(){
    int i;
    for (i = 0; i < nrNoduri; i++){
        listeAdiacenta[i].init();
        listeTranspuse[i].init();
    }
}

void citire(){
    FILE* fin = fopen("ctc.in", "r");
    int nrMuchii;
    int nod1, nod2;

    //fin >> nrNoduri >> nrMuchii;
    fscanf(fin, "%d%d", &nrNoduri, &nrMuchii);

    init();

    while(nrMuchii){
        //fin >> nod1 >> nod2;
        fscanf(fin, "%d\%d", &nod1, &nod2);
        nod1--;
        nod2--;
        listeAdiacenta[nod1].pushBack(nod2);
        listeTranspuse[nod2].pushBack(nod1);
        nrMuchii--;
    }

    fclose(fin);
}

void dfsPostOrdine(int nod);

void genPostOrdine(){
    int i;
    for (i = 0; i < nrNoduri; i++){
        if (!used[i]){
            dfsPostOrdine(i);
        }
    }
}

void dfsPostOrdine(int nod){
    int i;
    used[nod] = 1;
    for (i = 0; i < listeAdiacenta[nod].size; i++){
        if (!used[listeAdiacenta[nod].get(i)]){
            dfsPostOrdine(listeAdiacenta[nod].get(i));
        }
    }
    postOrdine[indPostOrdine++] = nod;
}

void dfsTranspus(int nod);

void genComponente(){
    int i;
    for (i = 0; i < nrNoduri; i++){
        used[i] = 0;
    }
    for (i = nrNoduri - 1; i >= 0; i--){
        if (!used[postOrdine[i]]){
            nrComponente++;
            dfsTranspus(postOrdine[i]);
        }
    }
}

void dfsTranspus(int nod){
    component[nod] = nrComponente;
    used[nod] = 1;
    int i;
    for (i = 0; i < listeTranspuse[nod].size; i++){
        if (!used[listeTranspuse[nod].get(i)]){
            dfsTranspus(listeTranspuse[nod].get(i));
        }
    }
}


void afisare(){
    int i, j;
    fout = fopen("ctc.out", "w");
    fprintf(fout, "%d\n", nrComponente);
    for (i = 1; i <= nrComponente; i++){
        for (j = 0; j < nrNoduri; j++){
            if (component[j] == i){
                break;
            }
        }
        fprintf(fout, "%d", j + 1);
        for (j++; j < nrNoduri; j++){
            if (component[j] == i){
                fprintf(fout, " %d", j + 1);
            }
        }
        fprintf(fout, "\n");
    }
    fclose(fout);
}

void str_Lista::init(){
    first = null;
    last = null;

    currentNode = null;
    currentIndex = -1;
    size = 0;
}

void str_Lista::pushBack(int info){
    str_NodLista* nod = new(str_NodLista);
    nod->info = info;
    nod->next = null;
    size++;
    if (first == null){
        first = nod;
        last = nod;
    }
    else{
        last->next = nod;
        last = nod;
    }
}

int str_Lista::get(int index){
    if (currentIndex != -1){
        if (index == currentIndex){
            return currentNode->info;
        }
        if (index == currentIndex + 1){
            currentNode = currentNode->next;
            currentIndex++;
            return currentNode->info;
        }
        if (index > currentIndex){
            while(currentIndex < index){
                currentNode = currentNode->next;
                currentIndex++;
            }
            return currentNode->info;
        }
    }
    currentIndex = 0;
    currentNode = first;
    while(currentIndex < index){
        currentNode = currentNode->next;
        currentIndex++;
    }
    return currentNode->info;
}