Cod sursa(job #2133484)

Utilizator preda.andreiPreda Andrei preda.andrei Data 17 februarie 2018 00:24:44
Problema Ciclu Eulerian Scor 100
Compilator c Status done
Runda Arhiva educationala Marime 3.48 kb
#include <stdio.h>
#include <stdlib.h>

typedef struct ListNode_m
{
  int value;
  struct ListNode_m *next;
} ListNode;

ListNode* CreateListNode(int val)
{
  ListNode *new_node = (ListNode*)malloc(sizeof(ListNode));
  new_node->value = val;
  new_node->next = NULL;
  return new_node;
}

typedef struct List_m
{
  ListNode *start;
  int size;
} List;

int ListIsEmpty(List *list)
{
  return list->start == NULL;
}

void AddToList(List *list, int val)
{
  ListNode *new_node = CreateListNode(val);
  new_node->next = list->start;
  list->start = new_node;
  list->size += 1;
}

void RemoveFromList(List *list, int val)
{
  if (list->start->value == val) {
    ListNode *to_delete = list->start;
    list->start = to_delete->next;
    free(to_delete);
    list->size -= 1;
    return;
  }

  ListNode *it = list->start;
  while (it->next != NULL) {
    if (it->next->value == val) {
      ListNode *to_delete = it->next;
      it->next = to_delete->next;
      free(to_delete);
      list->size -= 1;
      break;
    }
    it = it->next;
  }
}

int GetFromList(List *list, int ind)
{
  ListNode *it = list->start;
  while (ind > 0 && it != NULL) {
    it = it->next;
    ind -= 1;
  }
  return (it == NULL ? (-1) : it->value);
}

typedef List Stack;

int StackIsEmpty(Stack *stack)
{
  return ListIsEmpty(stack);
}

void AddToStack(Stack *stack, int val)
{
  AddToList(stack, val);
}

void RemoveFromStack(Stack *stack)
{
  if (StackIsEmpty(stack)) {
    return;
  }

  ListNode *to_delete = stack->start;
  stack->start = to_delete->next;
  free(to_delete);
  stack->size -= 1;
}

int StackTop(Stack *stack)
{
  if (StackIsEmpty(stack)) {
    return -1;
  }
  return stack->start->value;
}

typedef struct GraphNode_m
{
  List edges;
} GraphNode;

typedef GraphNode* Graph;

Graph CreateGraph(int size)
{
  Graph graph = (Graph)malloc(sizeof(GraphNode) * size);
  int i;

  for (i = 0; i < size; ++i) {
    graph[i].edges.start = NULL;
    graph[i].edges.size = 0;
  }
  return graph;
}

int Dfs(Graph graph, int node, char *visited)
{
  int count = 1;
  visited[node] = 1;

  ListNode *it = graph[node].edges.start;
  while (it != NULL) {
    int son = it->value;
    if (!visited[son]) {
      count += Dfs(graph, son, visited);
    }
    it = it->next;
  }
  return count;
}

int IsEulerian(Graph graph, int size)
{
  int i;
  for (i = 0; i < size; ++i) {
    if (graph[i].edges.size % 2 != 0) {
      return 0;
    }
  }

  char *visited = (char*)calloc(size, sizeof(char));
  int count = Dfs(graph, 0, visited);

  free(visited);
  return count == size;
}

int main()
{
  FILE *fin = fopen("ciclueuler.in", "r");
  FILE *fout = fopen("ciclueuler.out", "w");

  int nodes, edges;
  fscanf(fin, "%d%d", &nodes, &edges);

  Graph graph = CreateGraph(nodes);
  int i;

  for (i = 0; i < edges; ++i) {
    int x, y;
    fscanf(fin, "%d%d", &x, &y);
    AddToList(&graph[x - 1].edges, y - 1);
    AddToList(&graph[y - 1].edges, x - 1);
  }
  fclose(fin);

  if (!IsEulerian(graph, nodes)) {
    fprintf(fout, "-1\n");
    return 0;
  }

  Stack stack = {NULL};
  AddToStack(&stack, 0);

  while (!StackIsEmpty(&stack)) {
    int node = StackTop(&stack);
    int son = -1;

    if (ListIsEmpty(&graph[node].edges)) {
      if (stack.size > 1) {
        fprintf(fout, "%d ", node + 1);
      }
      RemoveFromStack(&stack);

    } else {
      son = GetFromList(&graph[node].edges, 0);
      RemoveFromList(&graph[node].edges, son);
      RemoveFromList(&graph[son].edges, node);
      AddToStack(&stack, son);
    }
  }
  free(graph);
  fclose(fout);

  return 0;
}