Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
JJ
Inlupp0
Commits
bb4f47d8
Commit
bb4f47d8
authored
2 weeks ago
by
JJ
💬
Browse files
Options
Download
Email Patches
Plain Diff
Add new file
parent
97b72830
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
473 additions
and
0 deletions
+473
-0
julafton.c
julafton.c
+473
-0
No files found.
julafton.c
0 → 100644
View file @
bb4f47d8
#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
\n
6. 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
;
}
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment