Commit bb4f47d8 authored by JJ's avatar JJ 💬
Browse files

Add new file

parent 97b72830
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include "string.h"
#include <stdbool.h>
#define MAX_NODES 100
typedef struct Edge {
int source;
int target;
int weight;
} Edge;
typedef struct Node {
int data;
struct Node *next;
} Node;
typedef struct Graph {
int V;
int E;
Edge *edges;
Node **adjList;
} Graph;
Graph* createGraph(int V, int E) {
Graph *graph = (Graph*)malloc(sizeof(Graph));
graph->V = V;
graph->E = 0;
graph->edges = (Edge*)malloc(E * sizeof(Edge));
graph->adjList = (Node**)malloc(V * sizeof(Node*));
for (int i = 0; i < V; i++) graph->adjList[i] = NULL;
return graph;
}
void addEdge(Graph *graph, int src, int dest, int weight) {
Node *newNode = (Node*)malloc(sizeof(Node));
newNode->data = dest;
newNode->next = graph->adjList[src];
graph->adjList[src] = newNode;
graph->edges[graph->E].source = src;
graph->edges[graph->E].target = dest;
graph->edges[graph->E].weight = weight;
graph->E++;
}
void DFS(Graph *graph, int v, bool visited[], Node **stack) {
visited[v] = true;
Node *adjNode = graph->adjList[v];
while (adjNode != NULL) {
if (!visited[adjNode->data]) {
DFS(graph, adjNode->data, visited, stack);
}
adjNode = adjNode->next;
}
Node *newNode = (Node*)malloc(sizeof(Node));
newNode->data = v;
newNode->next = *stack;
*stack = newNode;
}
Graph* getTranspose(Graph *graph) {
Graph *transpose = createGraph(graph->V, graph->E);
for (int v = 0; v < graph->V; v++) {
Node *adjNode = graph->adjList[v];
while (adjNode != NULL) {
addEdge(transpose, adjNode->data, v, 0);
adjNode = adjNode->next;
}
}
return transpose;
}
void DFSUtil(Graph *graph, int v, bool visited[], int *component, int compID, int *size) {
visited[v] = true;
component[v] = compID;
(*size)++;
Node *adjNode = graph->adjList[v];
while (adjNode != NULL) {
if (!visited[adjNode->data]) {
DFSUtil(graph, adjNode->data, visited, component, compID, size);
}
adjNode = adjNode->next;
}
}
void findSCCs(Graph *graph, int *component, int *componentSize, int *sccCount) {
Node *stack = NULL;
bool *visited = (bool*)calloc(graph->V, sizeof(bool));
for (int i = 0; i < graph->V; i++) if (!visited[i]) DFS(graph, i, visited, &stack);
Graph *transpose = getTranspose(graph);
for (int i = 0; i < graph->V; i++) visited[i] = false;
*sccCount = 0;
while (stack != NULL) {
int v = stack->data;
stack = stack->next;
if (!visited[v]) {
int size = 0;
DFSUtil(transpose, v, visited, component, *sccCount, &size);
componentSize[*sccCount] = size;
(*sccCount)++;
}
}
free(visited);
}
bool hasNegativeCycle(Graph *graph, int *component, int compID) {
int *dist = (int*)malloc(graph->V * sizeof(int));
for (int i = 0; i < graph->V; i++) dist[i] = INT_MAX;
for (int i = 0; i < graph->V; i++) {
if (component[i] == compID) {
dist[i] = 0;
break;
}
}
for (int i = 0; i < graph->V - 1; i++) {
for (int j = 0; j < graph->E; j++) {
int u = graph->edges[j].source, v = graph->edges[j].target, w = graph->edges[j].weight;
if (component[u] != compID || component[v] != compID) continue;
if (dist[u] != INT_MAX && dist[u] + w < dist[v]) dist[v] = dist[u] + w;
}
}
for (int j = 0; j < graph->E; j++) {
int u = graph->edges[j].source, v = graph->edges[j].target, w = graph->edges[j].weight;
if (component[u] != compID || component[v] != compID) continue;
if (dist[u] != INT_MAX && dist[u] + w < dist[v]) return true;
}
return false;
}
int findHarrysRoom(Graph *graph, int *component, int compID) {
int *inDeg = calloc(graph->V, sizeof(int));
for (int i = 0; i < graph->V; i++) {
if (component[i] != compID) continue;
Node *adj = graph->adjList[i];
while (adj != NULL) {
if (component[adj->data] == compID) inDeg[adj->data]++;
adj = adj->next;
}
}
int maxIn = -1, room = -1;
for (int i = 0; i < graph->V; i++) {
if (component[i] == compID && inDeg[i] > maxIn) {
maxIn = inDeg[i];
room = i;
}
}
free(inDeg);
return room;
}
int findStart(Graph *graph) {
int *in = calloc(graph->V, sizeof(int));
for (int i = 0; i < graph->V; i++) {
Node *adj = graph->adjList[i];
while (adj) {
in[adj->data]++;
adj = adj->next;
}
}
for (int i = 0; i < graph->V; i++) if (in[i] == 0) return i;
return -1;
}
void findPath(Graph *graph, int src, int dest, int *component, int cursedID) {
int *dist = malloc(graph->V * sizeof(int));
int *prev = malloc(graph->V * sizeof(int));
for (int i = 0; i < graph->V; i++) dist[i] = INT_MAX, prev[i] = -1;
dist[src] = 0;
for (int i = 0; i < graph->V - 1; i++) {
for (int j = 0; j < graph->E; j++) {
int u = graph->edges[j].source, v = graph->edges[j].target, w = graph->edges[j].weight;
if (component[v] == cursedID) continue;
if (dist[u] != INT_MAX && dist[u] + w < dist[v]) {
dist[v] = dist[u] + w;
prev[v] = u;
}
}
}
if (dist[dest] == INT_MAX) {
printf("5. Path: No valid path\n6. Energy: N/A\n");
return;
}
printf("5. Path: ");
int path[MAX_NODES], size = 0, curr = dest;
while (curr != -1) {
path[size++] = curr;
curr = prev[curr];
}
for (int i = size - 1; i >= 0; i--) printf("%d%s", path[i] + 1, (i ? " -> " : "\n"));
printf("6. Energy consumed/gained: %d\n", dist[dest]);
free(dist); free(prev);
}
void processGraph(Graph *graph) {
int component[MAX_NODES], componentSize[MAX_NODES], sccCount = 0;
findSCCs(graph, component, componentSize, &sccCount);
int max1 = -1, max2 = -1, id1 = -1, id2 = -1;
for (int i = 0; i < sccCount; i++) {
if (componentSize[i] > max1) {
max2 = max1; id2 = id1;
max1 = componentSize[i]; id1 = i;
} else if (componentSize[i] > max2) {
max2 = componentSize[i]; id2 = i;
}
}
int cursedID = hasNegativeCycle(graph, component, id1) ? id1 : id2;
int friendsID = cursedID == id1 ? id2 : id1;
int start = findStart(graph);
printf("1. Harry initially finds himself lost in room: %d\n", start + 1);
printf("2. Cursed rooms: ");
bool first = true;
for (int i = 0; i < graph->V; i++) {
if (component[i] == cursedID) {
if (!first) printf(", ");
printf("%d", i + 1);
first = false;
}
}
printf("\n");
int harrysRoom = findHarrysRoom(graph, component, friendsID);
int friends = 0;
for (int i = 0; i < graph->V; i++) if (component[i] == friendsID && i != harrysRoom) friends++;
printf("3. Harry has %d friends\n", friends);
printf("4. Harry's room is: %d\n", harrysRoom + 1);
printf("Harry's friends are in rooms: ");
first = true;
for (int i = 0; i < graph->V; i++) {
if (component[i] == friendsID && i != harrysRoom) {
if (!first) printf(", ");
printf("%d", i + 1);
first = false;
}
}
printf("\n");
findPath(graph, start, harrysRoom, component, cursedID);
}
Graph* loadGraphFromMatrix(int matrix[MAX_NODES][MAX_NODES], int size) {
int edgeCount = 0;
for (int i = 0; i < size; i++)
for (int j = 0; j < size; j++)
if (matrix[i][j] != 0) edgeCount++;
Graph *g = createGraph(size, edgeCount);
for (int i = 0; i < size; i++)
for (int j = 0; j < size; j++)
if (matrix[i][j] != 0) addEdge(g, i, j, matrix[i][j]);
return g;
}
void read_File_Graph(int graph[MAX_NODES][MAX_NODES], const char *filename)
{
FILE *file = fopen(filename, "r"); // Open file for reading
if (!file)
{
printf("Error opening file!\n"); // Error message if file can't be opened
exit(1);
}
char buffer[1024]; // Buffer to store a line from the file
if (!fgets(buffer, sizeof(buffer), file)) // Read the first line from the file
{
printf("Error, empty file!\n"); // If the file is empty
exit(1);
}
rewind(file); // Rewind the file pointer back to the beginning of the file
int number_of_rows = 0;
//
char *value = strtok(buffer, " \t\n"); // Split the first line into values
while (value != NULL)
{
number_of_rows += 1;
value = strtok(NULL, " \t\n"); // Get next value
}
rewind(file); // Rewind the file pointer back to the beginning of the file
for (int i = 0; i < number_of_rows; i++) // Loop through all rows in the adjacency matrix
{
for (int j = 0; j < number_of_rows; j++) // Loop through all columns in the adjacency matrix
{
// Read a value from the file
if (fscanf(file, "%d", &graph[i][j]) != 1)
{
printf("Error, invalid matrix format at row %d, column %d!\n", i, j);
exit(1);
}
}
}
fclose(file); // Close the file
}
int main() {
int g1[MAX_NODES][MAX_NODES];
read_File_Graph(g1, "./g1.txt");
printf("=== G1 ===\n");
Graph *graph1 = loadGraphFromMatrix(g1, 8);
processGraph(graph1);
int g2[MAX_NODES][MAX_NODES];
read_File_Graph(g2, "./g2.txt");
printf("\n=== G2 ===\n");
Graph *graph2 = loadGraphFromMatrix(g2, 13);
processGraph(graph2);
int g3[MAX_NODES][MAX_NODES];
read_File_Graph(g3, "./g3.txt");
printf("\n=== G3 ===\n");
Graph *graph3 = loadGraphFromMatrix(g3, 13);
processGraph(graph3);
return 0;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment