I was tasked my my prof to solve a graph question. However, he hinted that one of his hidden test cases that I failed have over 80k, my code would fail as it exceeded the amount of memory that was preassigned.
#include<stdio.h>
#include <stdlib.h>
int* city_population (int N, int* population, int** road, int Q, int** cities) ;
int main() {
int N;
scanf("%d", &N);
int i_population;
int *population = (int *)malloc(sizeof(int)*(N));
for(i_population = 0; i_population < N; i_population++)
scanf("%d", &population[i_population]);
int i_road, j_road;
int **road = (int **)malloc((N-1)*sizeof(int *));
for(i_road = 0; i_road < N-1; i_road++)
{
road[i_road] = (int *)malloc((2)*sizeof(int));
}
for(i_road = 0; i_road < N-1; i_road++)
{
for(j_road = 0; j_road < 2; j_road++)
{
scanf("%d", &road[i_road][j_road]);
}
}
int Q;
scanf("%d", &Q);
int i_cities, j_cities;
int **cities = (int **)malloc((Q)*sizeof(int *));
for(i_cities = 0; i_cities < Q; i_cities++)
{
cities[i_cities] = (int *)malloc((3)*sizeof(int));
}
for(i_cities = 0; i_cities < Q; i_cities++)
{
for(j_cities = 0; j_cities < 3; j_cities++)
{
scanf("%d", &cities[i_cities][j_cities]);
}
}
int* out_ = city_population(N, population, road, Q, cities);
printf("%d", out_[0]);
int i_out_;
for(i_out_ = 1; i_out_ < Q; i_out_++)
printf("\n%d", out_[i_out_]);
}
This is my implementation of the function with adjacency matrix. However, it is not optimal but I do not know how to implement an optimized code to solve it. The comments above the code is what I had debunked from the template that my prof have provided in creating this question.
roads : they are the edges/link that ties the 2 cities/vertex together
cities: It is a Q x 3 matrix where Q is the number of query. so
cities[][0] denotes the start of a city/vertex
cities denotes the end of a city/vertex
cities[][2] denotes the condition to look for city between the 2 determined vertex that have <= cities[2]
What I did was I created an adjacency matrix to store the edges and implemented a depth first search to find out how many city between the 2 determined vertex have a population less than or equal to cities[][2]
// count[i] is the number of cities with population less than or equal to cities[i][2]
// Start of city is denoted by cities[i][0] and end of city is denoted by cities[i][1]
// The road is undirected and there is only one road between two cities
// Traverse the start city to the end city with the road
// Traverse with depth first search with stack
// Return an array of count of cities that satisfy the above condition
//Consider N = 3 , population = [1,2,3], road = [[1,2],[2,3]], Q = 2, cities = [[1,3,2]]
// The given query is the number of cities in the path from 1 to 3 that have a population of at most2
//cities lie in the path are [1,2,3]. so the answer will return 2
int* city_population (int N, int* population, int** road, int Q, int** cities)
{
int i,j;
// Count is the number of cities with population less than or equal to cities[i][2]
int *count = (int *)malloc(sizeof(int)*Q);
// Visited is to check if the city is visited or not
int *visited = (int *)malloc(sizeof(int)*N);
// Stack is the stack to traverse the cities
int *sTemp = (int *)malloc(sizeof(int)*N);
int top;
// Adjacency matrix
int **adjV = (int **)malloc((N)*sizeof(int *));
for(i=0;i<N;i++)
adjV[i] = (int *)malloc((N)*sizeof(int));
for(i=0;i<N-1;i++){
adjV[road[i][0]-1][road[i][1]-1] = 1;
adjV[road[i][1]-1][road[i][0]-1] = 1;
}
// Traverse the cities with depth first search
for(i=0;i<Q;i++){
for(j=0;j<N;j++)
visited[j] = 0;
top = -1;
sTemp[++top] = cities[i][0]-1;
visited[cities[i][0]-1] = 1;
count[i] = 0;
while(top!=-1){
int curC = sTemp[top];
// Traverse the adjacency list of the current city
if(curC == cities[i][1]-1)
break;
for(j=0;j<N;j++){
if(adjV[curC][j] == 1 && visited[j] == 0)
{
sTemp[++top] = j;
visited[j] = 1;
break;
}
}
// If the current city is the last city in the adjacency list then pop the city from the stack
if(j==N)
top--;
}
// Count the number of cities with population less than or equal to cities[i][2]
for(j=0;j<=top;j++){
if(population[sTemp[j]]<=cities[i][2]){
count[i]++;
}
}
}
return count;
}
I am genuinely seeking advice on how the ways to optimize my code. Thanks.