#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct package {
char *ID;
int weight;
struct package *nextPtr;
};
typedef struct package Package;
typedef Package* PackagePtr;
struct postOffice {
int minWeight;
int maxWeight;
int packagesCount;
Package *packagesHeadPtr;
Package *packagesTailPtr;
};
typedef struct postOffice PostOffice;
struct town {
char name[6];
int officesCount;
PostOffice *offices;
};
typedef struct town Town;
void dequeue(PackagePtr *headPtr, PackagePtr *tailPtr) {
PackagePtr tempPtr = *headPtr;
*headPtr = (*headPtr)->nextPtr;
if(*headPtr == NULL) {
*tailPtr = NULL;
}
free(tempPtr->ID);
tempPtr->ID = NULL;
free(tempPtr);
tempPtr = NULL;
}
void enqueue(PackagePtr *headPtr, PackagePtr *tailPtr, char ID[], int weight) {
PackagePtr newPtr = malloc(sizeof(Package));
if (newPtr == NULL) {
exit(EXIT_FAILURE);
}
newPtr->ID = malloc(6 * sizeof(char));
newPtr->ID = ID;
newPtr->weight = weight;
newPtr->nextPtr = NULL;
if (*headPtr == NULL) {
*headPtr = newPtr;
} else {
(*tailPtr)->nextPtr = newPtr;
}
*tailPtr = newPtr;
}
int findTown(Town towns[], int townsCount, char townName[]) {
for (int i = 0; i < townsCount; i++) {
if (!strcmp(townName, towns[i].name)) {
return i;
}
}
return -1;
}
void sendAllAcceptablePackages(Town towns[], int sourceOfficeIndex, int targetOfficeIndex) {
PackagePtr currentPackage = towns[sourceOfficeIndex].offices->packagesHeadPtr;
while (currentPackage != NULL) {
if (currentPackage->weight >= towns[targetOfficeIndex].offices->minWeight &&
currentPackage->weight <= towns[targetOfficeIndex].offices->maxWeight
) {
enqueue(&towns[targetOfficeIndex].offices->packagesHeadPtr,
&towns[targetOfficeIndex].offices->packagesTailPtr,
towns[sourceOfficeIndex].offices->packagesHeadPtr->ID,
towns[sourceOfficeIndex].offices->packagesHeadPtr->weight
);
} else {
enqueue(&towns[sourceOfficeIndex].offices->packagesHeadPtr,
&towns[sourceOfficeIndex].offices->packagesTailPtr,
towns[sourceOfficeIndex].offices->packagesHeadPtr->ID,
towns[sourceOfficeIndex].offices->packagesHeadPtr->weight
);
}
dequeue(&towns[sourceOfficeIndex].offices->packagesHeadPtr,
&towns[sourceOfficeIndex].offices->packagesTailPtr
);
}
}
int main(int argc, char *argv[]) {
int townsCount, queries;
scanf("%i", &townsCount);
Town* towns = malloc(townsCount * sizeof(Town));
for (int i = 0; i < townsCount; i++) {
scanf("%s%i", towns[i].name, &towns[i].officesCount);
towns[i].offices = malloc(towns[i].officesCount * sizeof(PostOffice));
for (int j = 0; j < towns[i].officesCount; j++) {
scanf("%i%i%i",
&towns[i].offices[j].packagesCount,
&towns[i].offices[j].minWeight,
&towns[i].offices[j].maxWeight
);
towns[i].offices[j].packagesHeadPtr = NULL;
towns[i].offices[j].packagesTailPtr = NULL;
for (int k = 0; k < towns[i].offices[j].packagesCount; k++) {
char ID[6];
int weight;
scanf("%s%i", ID, &weight);
enqueue(&towns[i].offices[j].packagesHeadPtr,
&towns[i].offices[j].packagesTailPtr,
ID,
weight
);
}
}
}
scanf("%i", &queries);
while (queries--) {
char townName[6];
int type, sourceOfficeIndex, targetOfficeIndex, townIndex;
scanf("%i", &type);
switch (type) {
case 1:
scanf("%s", townName);
int townIndex = findTown(towns, townsCount, townName);
printf("%s:\n", towns[townIndex].name);
for (int i = 0; i < towns[townIndex].officesCount; i++) {
printf("\t%i:\n", i);
PackagePtr currentPackage = towns[townIndex].offices[i].packagesHeadPtr;
while (currentPackage != NULL) {
printf("\t\t%s\n", currentPackage->ID);
currentPackage = currentPackage->nextPtr;
}
}
break;
case 2:
scanf("%s%i%s%i", townName, &sourceOfficeIndex, townName, &targetOfficeIndex);
sendAllAcceptablePackages(towns, sourceOfficeIndex, targetOfficeIndex);
break;
case 3:
for (int i = 0, packages = 0, maxPackages = -1; i < townsCount; i++, packages = 0) {
for (int j = 0; j < towns[i].officesCount; j++) {
packages += towns[i].offices[j].packagesCount;
}
if (packages > maxPackages) {
maxPackages = packages;
townIndex = i;
}
}
printf("Town with the most number of packages is %s\n", towns[townIndex].name);
break;
}
}
return EXIT_SUCCESS;
}