/* Robert S Laramee
* CS391S/T
* 8 April 1997
* Assignment #1
*
* see end of program for required documentation
*/
#include<stdio.h>
#define WORKED 1
#define DIDNT_WORK 2
#define NUM_OF_NODES 56169 /** smallgraph = 128
** largegraph1 = 56,169
** largegraph2 = 16,384
**/
typedef enum { GREEN, RED, BLUE } colortype1;
typedef enum { WHITE, GRAY, BLACK } colortype2;
struct node_template {
colortype1 paint_color;
colortype2 visit_color;
int adjacent_nodes[50];
int predecessor;
};
struct node_template node_array[NUM_OF_NODES];
/** a variable for the DFS_Visit() function
**/
int parent = 0;
void Print_Cycle(int matching_node, int original_node) {
printf("This graph is not two-colorable.\n");
printf("Odd cycle starts at node %i and ends at node %i\n",
matching_node, original_node);
/* if (matching_node == original_node) {
printf(" done\n");
return;
}
matching_node = node_array[matching_node].predecessor;
Print_Cycle (matching_node, original_node);
*/
return;
}
/** The Depth First Search algorithm is on pg 478 of CLR
**/
int DFS_Visit(int u) {
int v = 0;
int number_adjacent = 0;
int adjacent_node;
parent = node_array[u].predecessor;
node_array[u].visit_color = GRAY;
if (node_array[parent].paint_color == RED) {
node_array[u].paint_color = BLUE;
} else {
node_array[u].paint_color = RED;
}
/** Find out how many adjacent nodes there are.
**/
while (node_array[u].adjacent_nodes[v] != 0) {
v++;
number_adjacent++;
}
for (v=0; v<number_adjacent; v++) {
adjacent_node = node_array[u].adjacent_nodes[v];
/** Look at all the adjacent nodes. If we find one with the same
** color, then we have an odd cycle. Print it out and return
** DIDNT_WORK
**/
if (node_array[adjacent_node].visit_color == GRAY) {
if (node_array[adjacent_node].paint_color ==
node_array[u].paint_color) {
Print_Cycle(adjacent_node, u);
return DIDNT_WORK;
}
}
if (node_array[adjacent_node].visit_color == WHITE) {
node_array[adjacent_node].predecessor = u;
if (DFS_Visit(adjacent_node) != 1) {
printf("Error with recursive call: DFS_Visit()\n");
}
return WORKED;
}
}
node_array[u].visit_color = BLACK;
return WORKED;
}
int Depth_First_Search() {
int u, return_value;
/** Initialize all vertices visit color to white and vertices predecessors
** to zero.
**/
for (u=1; u<NUM_OF_NODES+1; u++) {
node_array[u].visit_color = WHITE;
node_array[u].predecessor = 0;
}
for (u=1; u<NUM_OF_NODES+1; u++) {
if (node_array[u].visit_color == WHITE) {
return_value = DFS_Visit(u);
if (return_value != WORKED) {
return DIDNT_WORK;
}
}
}
return WORKED;
}
void main(void) {
int i = 0;
int j = 0;
int number_of_nodes = 0;
int current_node = 0;
int adjacent_node = 0;
FILE *graph_file_ptr;
/** Initialize all the adjacent nodes to zero.
**/
for (i=0; i<NUM_OF_NODES; i++) {
for(j=0; j<50; j++) {
node_array[i].adjacent_nodes[j] = 0;
}
}
/** Open the graph file.
**/
if ((graph_file_ptr = fopen("largegraph2", "r")) == NULL) {
printf("Error cannot open file 'smallgraph' for reading. \n");
}
/** Read in the number of nodes (|V|).
**/
fscanf(graph_file_ptr, "%i", &number_of_nodes);
/** Read the file one line at a time, and start building the adjacency
** list for each node
**/
while
(fscanf(graph_file_ptr, "%i %i\n", ¤t_node, &adjacent_node) == 2) {
i = 0;
/** Find the first empty slot in the current node's adjacency list
** and add the adjacent node to it.
**/
while (node_array[current_node].adjacent_nodes[i] != 0) { i++; }
node_array[current_node].adjacent_nodes[i] = adjacent_node;
i = 0;
/** Since this is an undirected graph we also have to
** find the first empty slot in the adjacent node's adjacency list
** and add the current node to it.
**/
while (node_array[adjacent_node].adjacent_nodes[i] != 0) { i++; }
node_array[adjacent_node].adjacent_nodes[i] = current_node;
}
if (fclose(graph_file_ptr)) {
printf("Problem closing smallgraph file...\n");
}
/** Start the Depth First Search algorithm.
**/
if (Depth_First_Search() == WORKED) {
printf("This graph is two-colorable.\n");
for (i=0; i<number_of_nodes; i++) {
j = 0;
while (node_array[i].adjacent_nodes[j] != 0) {
adjacent_node = node_array[i].adjacent_nodes[j];
printf("node = %i color = %i ", i, node_array[i].paint_color);
printf("adjacent node = %i paint_color = %i\n",
adjacent_node, node_array[adjacent_node].paint_color);
j++;
}
}
}
}
/** The Depth First Search algorithm on pg 478 of CLR was chosen
** because of it's running time. It runs in O(|V| + |E|) steps.
**
** Time of smallgraph
** el12> time assignment2
** 1.468u 0.756s 0:02.28 96.9% 0+66k 0+0io 0pf+0w
**
** Time of largegraph1
** el12> time assignment2
** 9.699u 0.853s 0:11.49 91.7% 0+106k 0+1io 0pf+0w
**
** Time of largegraph2
** el12> time assignment2
** 10.887u 0.880s 0:12.60 93.3% 0+108k 0+1io 0pf+0w
**
** el12> machine
** alpha