Cod sursa(job #1307379)

Utilizator alex_gabAlex Dragoi alex_gab Data 2 ianuarie 2015 01:24:10
Problema Parcurgere DFS - componente conexe Scor 100
Compilator c Status done
Runda Arhiva educationala Marime 5.12 kb
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

const char *IN_FILE_NAME = "dfs.in";
const char *OUT_FILE_NAME = "dfs.out";

typedef struct AdjacencyListVertex {
    int destination;
    struct AdjacencyListVertex *next;
} AdjacencyListVertex;

typedef struct AdjacencyList {
    AdjacencyListVertex *head;
} AdjacencyList;

typedef struct Graph {
    int numberOfVertices;
    AdjacencyList *adjacencyLists;
} Graph;

typedef struct stack {
    int value;
    struct stack *previous;
} stack;

int visited[100001];
int numberOfVertices, numberOfEdges, numberOfConnectedComponents;

Graph *createGraph(int numberOfVertices);

void addEdge(Graph *graph, int source, int destination);

void printGraph(Graph *graph);

void freeGraph(Graph *graph);

Graph *readInput();

void push(stack **top, int data);

int isEmpty(stack *top);

int pop(stack **top);

void writeOutput();

int main(int argc, char *argv[]) {
    Graph *graph = readInput();

    stack *top = NULL;
    int i;
    for (i = 0; i < numberOfVertices; ++i) {
        if (!visited[i]) {
            push(&top, i);
            numberOfConnectedComponents++;
            while (!isEmpty(top)) {
                int vertexIndex = pop(&top);
                if (!visited[vertexIndex]) {
                    visited[vertexIndex] = 1;
                    AdjacencyListVertex *neighbour = graph->adjacencyLists[vertexIndex].head;
                    while (neighbour) {
                        if (!visited[neighbour->destination]) {
                            push(&top, neighbour->destination);
                        }
                        neighbour = neighbour->next;
                    }
                }
            }
        }
    }
    freeGraph(graph);
    writeOutput();
    return 0;
}

Graph *readInput() {
    FILE *inputFile = freopen(IN_FILE_NAME, "r", stdin);
    scanf("%d %d", &numberOfVertices, &numberOfEdges);

    Graph *graph = createGraph(numberOfVertices);
    int i, firstVertexInEdge, secondVertexInEdge;
    for (i = 0; i < numberOfEdges; i++) {
        scanf("%d %d", &firstVertexInEdge, &secondVertexInEdge);
        addEdge(graph, firstVertexInEdge - 1, secondVertexInEdge - 1);
    }
    fclose(inputFile);

    return graph;
}

void writeOutput() {
    FILE *outputFile = freopen(OUT_FILE_NAME, "w", stdout);
    printf("%d\n", numberOfConnectedComponents);
    fclose(outputFile);
}

AdjacencyListVertex *newAdjacencyListNode(int destination) {
    AdjacencyListVertex *newNode = malloc(sizeof(AdjacencyListVertex));
    newNode->destination = destination;
    newNode->next = NULL;
    return newNode;
}

Graph *createGraph(int numberOfVertices) {
    Graph *graph = malloc(sizeof(Graph));
    graph->numberOfVertices = numberOfVertices;

    AdjacencyList *adjacencyList = malloc(numberOfVertices * sizeof(AdjacencyList));
    graph->adjacencyLists = adjacencyList;

    int i;
    for (i = 0; i < numberOfVertices; ++i) {
        adjacencyList[i].head = NULL;
    }
    return graph;
}

void addEdge(Graph *graph, int source, int destination) {
    AdjacencyListVertex *newVertex = newAdjacencyListNode(destination);
    newVertex->next = graph->adjacencyLists[source].head;
    graph->adjacencyLists[source].head = newVertex;

    AdjacencyListVertex *homologous = newAdjacencyListNode(source);
    homologous->next = graph->adjacencyLists[destination].head;
    graph->adjacencyLists[destination].head = homologous;
}

void printGraph(Graph *graph) {
    AdjacencyList *adjacencyLists = graph->adjacencyLists;
    int node;
    for (node = 0; node < graph->numberOfVertices; ++node) {
        AdjacencyListVertex *crawlVertex = adjacencyLists[node].head;
        printf("\n Adjacency list of vertex %d\n head ", node);
        while (crawlVertex) {
            printf("-> %d", crawlVertex->destination);
            crawlVertex = crawlVertex->next;
        }
        printf("\n");
    }
}

void freeGraph(Graph *graph) {
    AdjacencyList *adjacencyLists = graph->adjacencyLists;
    int node;
    for (node = 0; node < graph->numberOfVertices; ++node) {
        AdjacencyListVertex *crawlVertex = adjacencyLists[node].head;
        while (crawlVertex) {
            AdjacencyListVertex *toBeFreed = crawlVertex;
            crawlVertex = crawlVertex->next;
            free(toBeFreed);
        }
    }
    free(adjacencyLists);
    free(graph);
}

int isEmpty(stack *top) {
    if (top == NULL) {
        return 1;
    } else {
        return 0;
    }
}

void push(stack **top, int data) {
    if (isEmpty(*top)) {
        *top = malloc(sizeof(stack));
        memset(*top, 0, sizeof(stack));
        (*top)->value = data;
        (*top)->previous = NULL;
    } else {
        stack *newTop = malloc(sizeof(stack));
        memset(newTop, 0, sizeof(stack));
        newTop->previous = *top;
        newTop->value = data;
        *top = newTop;
    }
}

int pop(stack **top) {
    stack *oldTop = *top;
    int data = oldTop->value;
    if (!isEmpty(*top)) {
        *top = oldTop->previous;
        free(oldTop);
    }

    return data;
}