Cod sursa(job #2892144)

Utilizator cosmin.vasilacheVasilache Cosmin George cosmin.vasilache Data 20 aprilie 2022 22:45:28
Problema Parcurgere DFS - componente conexe Scor 5
Compilator c-64 Status done
Runda Arhiva educationala Marime 8.74 kb
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// ADJACENCY MATRIX
typedef struct graphMatrix
{
	int **adjacencyMatrix;
	int numNodes;
} graphMatrix;

// EDGES
typedef struct edge
{
	int leftNode;
	int rightNode;
} edge;

typedef struct graphEdges
{
	edge *edges;
	int numNodes;
	int numEdges;
} graphEdges;

// POINTERS/VERTEX
typedef struct vertex
{
	int name;
	struct vertex **neighbors;
	int numNeighbors;
	//	int* weights;
} vertex;

typedef struct graphVertex
{
	int numNodes;
	int numEdges;
	vertex **nodes;
} graphVertex;

int stack[100];
int indexStack = 0;

void push(int value)
{
	if (indexStack < 100)
		stack[indexStack++] = value;
	else
		printf("Dimensiune stiva depasita!\n");
}

int pop()
{
	// verificare daca sunt elemente in stiva
	if (indexStack > 0)
	{
		int value = stack[--indexStack];
		stack[indexStack] = 0;
		return value;
	}
	printf("Stiva este goala!\n");
	return (int)0;
}

int tail[100];
int indexTail = 0;

void push_tail(int value)
{
	if (indexTail < 100)
		tail[indexTail++] = value;
	else
		puts("coada plina");
}

int pop_tail()
{
	if (indexTail > 0)
	{
		int k = tail[0];

		for (int i = 0; i < indexTail - 1; i++)
			tail[i] = tail[i + 1];

		tail[--indexTail] = 0;
		return k;
	}
	else
		puts("coada goala");
}

void bfs_matrix(graphMatrix graph, int startNode, int *visited)
{
	int n = graph.numNodes;
	push_tail(startNode);
	int k;
	while (indexTail > 0)
	{
		k = pop_tail();
		printf("%d ", k);
		visited[k] = 1;

		for (int i = 0; i < n; i++)
			if (graph.adjacencyMatrix[k][i] && visited[i] == 0)
			{
				push_tail(i);
				visited[i] = 1;
			}
	}
}

void dfs_matrix(graphMatrix graph, int currentNode, int *visited)
{

	int n = graph.numNodes;

	if (visited[currentNode] == 0)
	{
		printf("%d ", currentNode);
		visited[currentNode] = 1;
	}
	for (int i = 0; i < n; i++)
		if (graph.adjacencyMatrix[currentNode][i] && !visited[i])
		{
			dfs_matrix(graph, i, visited);
		}
}

graphMatrix readGraphMatrix(const char *fileName)
{
	FILE *f = fopen(fileName, "r");
	graphMatrix graph;
	graph.numNodes = 0;
	if (f == NULL)
		return graph;

	fscanf(f, "%d", &(graph.numNodes));
	int n = graph.numNodes;
	graph.adjacencyMatrix = (int **)malloc(graph.numNodes * sizeof(int *));

	for (int i = 0; i < n; i++)
		graph.adjacencyMatrix[i] = (int *)malloc(n * sizeof(int));

	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
			fscanf(f, "%d", &(graph.adjacencyMatrix[i][j]));

	// TODO

	fclose(f);
	return graph;
}

void bfs_edges(graphEdges graph, int startNode, int *visited)
{
	int n = graph.numEdges;
	push_tail(startNode);

	int k;

	while (indexTail > 0)
	{
		k = pop_tail();
		printf("%d ", k);
		visited[k] = 1;

		for (int i = 0; i < n; i++)
			if (graph.edges[i].leftNode == k && !visited[graph.edges[i].rightNode])
			{
				push_tail(graph.edges[i].rightNode);
				visited[graph.edges[i].rightNode] = 1;
			}
	}
}

void dfs_edges(graphEdges graph, int currentNode, int *visited)
{
	if (visited[currentNode] == 0)
	{
		printf("%d ", currentNode);
		visited[currentNode] = 1;
	}

	for (int i = 0; i < graph.numEdges; i++)
		if (graph.edges[i].leftNode == currentNode && !visited[graph.edges[i].rightNode])
		{
			dfs_edges(graph, graph.edges[i].rightNode, visited);
		}
}

graphEdges readGraphEdgeList(const char *fileName)
{
	graphEdges graph;
	graph.numEdges = 0;
	graph.edges = NULL;
	FILE *f = fopen(fileName, "r");
	if (f == NULL)
		return graph;

	// TODO

	fscanf(f, "%d", &(graph.numNodes));
	fscanf(f, "%d", &(graph.numEdges));

	graph.edges = (edge *)malloc(graph.numEdges * sizeof(edge));

	for (int i = 0; i < graph.numEdges; i++)
		fscanf(f, "%d %d", &(graph.edges[i].leftNode), &(graph.edges[i].rightNode));

	fclose(f);
	return graph;
}

void bfs_pointers(graphVertex graph, int startNode, int *visited)
{
	push_tail(startNode);
	int k;

	while (indexTail > 0)
	{
		k = pop_tail();

		printf("%d ", k);
		visited[k] = 1;

		for (int i = 0; i < graph.nodes[k]->numNeighbors; i++)
			if (visited[graph.nodes[k]->neighbors[i]->name] == 0)
			{
				push_tail(graph.nodes[k]->neighbors[i]->name);
				visited[graph.nodes[k]->neighbors[i]->name] = 1;
			}
	}
}

void dfs_pointers(graphVertex graph, int currentNode, int *visited)
{
	if (!visited[currentNode])
	{
		printf("%d ", currentNode);
		visited[currentNode] = 1;
	}

	for (int i = 0; i < graph.nodes[currentNode]->numNeighbors; i++)
	{
		if (visited[graph.nodes[currentNode]->neighbors[i]->name] == 0)
		{
			dfs_pointers(graph, graph.nodes[currentNode]->neighbors[i]->name, visited);
		}
	}
}

graphVertex readGraphVertex(const char *fileName)
{
	graphVertex graph;
	graph.numEdges = 0;
	graph.numNodes = 0;
	FILE *f = fopen(fileName, "r");
	if (f == NULL)
		return graph;

	fscanf(f, "%i%i", &(graph.numNodes), &(graph.numEdges));
	graph.nodes = (vertex **)malloc(sizeof(vertex *) * graph.numNodes);

	for (int i = 0; i < graph.numNodes; i++)
	{
		graph.nodes[i] = (vertex *)malloc(sizeof(vertex));
	}

	if (graph.nodes == NULL)
		return graph;
	for (int i = 0; i < graph.numNodes; i++)
	{
		graph.nodes[i]->name = i;
		graph.nodes[i]->numNeighbors = 0;
		graph.nodes[i]->neighbors = NULL;
	}

	graphEdges graphE = readGraphEdgeList(fileName);

	int *copii = (int *)malloc(graph.numNodes * sizeof(int));
	// int n = graph.numNodes;
	for (int i = 0; i < graph.numNodes; i++)
		copii[i] = 0;

	for (int i = 0; i < graphE.numEdges; i++)
		copii[graphE.edges[i].leftNode]++;

	/*  int left,right;
	 for (int i = 0; i < graph.numEdges; i++)
	 {
		 fscanf(f,"%d %d",left,right);
		 // TODO
		 for(int j=0;j<graph.numNodes;j++)

	 }*/
	fclose(f);

	for (int i = 0; i < graph.numNodes; i++)
	{
		graph.nodes[i]->name = i;
		graph.nodes[i]->numNeighbors = copii[i];
		graph.nodes[i]->neighbors = (vertex **)malloc(copii[i] * sizeof(vertex *));

		for (int j = 0; j < copii[i]; j++)
		{
			graph.nodes[i]->neighbors[j] = (vertex *)malloc(sizeof(vertex));
		}
	}

	for (int i = 0; i < graph.numNodes; i++)
	{
		int k = 0;
		for (int j = 0; j < graph.numEdges; j++)
		{
			if (i == graphE.edges[j].leftNode)
			{
				graph.nodes[i]->neighbors[k]->name = graphE.edges[j].rightNode;
				graph.nodes[i]->neighbors[k]->numNeighbors = copii[graphE.edges[j].rightNode];
				k++;
			}
		}
	}

	for (int i = 0; i < graph.numNodes; i++)
	{
		for (int j = 0; j < graph.nodes[i]->numNeighbors; j++)
			graph.nodes[i]->neighbors[j] = graph.nodes[graph.nodes[i]->neighbors[j]->name];
	}

	return graph;
}

int full(int *v, int n)
{
	for (int i = 0; i < n; i++)
		if (!v[i])
			return 0;

	return 1;
}

void DFS_pointers(graphVertex graph, int currentNode, int *visited, int **c)
{
	if (!visited[currentNode])
	{
		// printf("%d ", currentNode);
		visited[currentNode] = 1;
		(*c)[currentNode] = 1;
	}

	for (int i = 0; i < graph.nodes[currentNode]->numNeighbors; i++)
	{
		if (visited[graph.nodes[currentNode]->neighbors[i]->name] == 0)
		{
			DFS_pointers(graph, graph.nodes[currentNode]->neighbors[i]->name, visited, &(*c));
		}
	}
}

void DFS_infoarena(const char *file)
{
	graphVertex graph = readGraphVertex(file);

	int n = graph.numNodes;
	int *checked = (int *)malloc(n * sizeof(int));
	int *visited = (int *)malloc(n * sizeof(int));
	for (int i = 0; i < n; i++)
	{
		checked[i] = 0;
		visited[i] = 0;
	}

	int conexe = 0;

	for (int i = 0; i < n && !full(checked, n); i++)
	{
		while (checked[i])
			i++;

		conexe++;
		DFS_pointers(graph, i, visited, &checked);

		/*	for (int j = 0; j < n; j++)
			printf("%d ", checked[j]);

			puts(" ");*/
	}

	FILE *f;
	f = fopen("dfs.out", "w");

	fprintf(f, "%d", conexe);

	fclose(f);
}

int main()
{
	// ADJACENCY MATRIX
	/*	graphMatrix graphM = readGraphMatrix("graphMatrix.txt");
		int visited[100] = {0}; // we assume fewer than 100 nodes
		dfs_matrix(graphM, 0, visited);
		printf("\n");
		int visited1[100] = {0}; // we assume fewer than 100 nodes
		bfs_matrix(graphM, 0, visited1);
		printf("\n");
		// EDGES
		graphEdges graphE = readGraphEdgeList("graphEdges.txt");
		int visited2[100] = {0}; // we assume fewer than 100 nodes
		dfs_edges(graphE, 0, visited2);
		printf("\n");
		int visited3[100] = {0}; // we assume fewer than 100 nodes
		bfs_edges(graphE, 0, visited3);
		printf("\n");
		// POINTERS/VERTEX
		graphVertex graphV = readGraphVertex("graphEdges.txt");
		int visited4[100] = {0}; // we assume fewer than 100 nodes
		dfs_pointers(graphV, 0, visited4);
		printf("\n");
		int visited5[100] = {0}; // we assume fewer than 100 nodes
		bfs_pointers(graphV, 0, visited5);
		printf("\n");*/

	DFS_infoarena("dfs.in");
	printf("\n\n\n");
	return 0;
}