-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.cpp
198 lines (174 loc) · 5.72 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
/*
L'entrée représente une liste de connexions entre villes et leurs distances.
Partie 1 : Trouver le chemin le plus court passant par toutes les villes une seule fois.
Partie 2 : Trouver le chemin le plus long passant par toutes les villes une seule fois.
*/
#include <algorithm>
#include <fstream>
#include <iostream>
#include <string>
#include <unordered_map>
#include <vector>
#include <Utils/MeasureExecutionTime.cpp>
#include <Utils/SplitString.cpp>
using namespace std;
// Structure représentant la distance entre deux villes
struct CityDistance
{
string from; // Ville de départ
string to; // Ville de destination
int distance; // Distance entre les deux villes
};
// Classe représentant un nœud dans le contexte du problème
class Node
{
public:
string actualCity; // Ville actuelle du nœud
int totalDistance; // Distance totale parcourue jusqu'à ce nœud
vector<string> history; // Historique des villes visitées jusqu'à ce nœud
// Constructeur pour initialiser un nœud avec une nouvelle ville
Node(string actualCity, string to, int totalDistance)
{
this->actualCity = to;
this->totalDistance = totalDistance;
history.push_back(actualCity);
history.push_back(to);
}
// Surcharge de l'opérateur d'assignation
Node &operator=(const Node &other)
{
actualCity = other.actualCity;
totalDistance = other.totalDistance;
history = other.history;
return *this;
}
};
// Table de hachage utilisant une unordered_map, associant chaque ville à une liste de distances vers d'autres villes
unordered_map<string, vector<CityDistance>> hashtable;
// Fonction pour analyser les données d'entrée à partir d'un fichier
int parseInput()
{
MEASURE_FUNCTION_EXECUTION_TIME
string filename = "input.txt";
ifstream file(filename);
if (!file.is_open())
{
cerr << "Erreur : impossible d'ouvrir le fichier " << filename;
return 1;
}
string line;
while (getline(file, line))
{
vector<string> splitedInput = splitString(line, " ");
hashtable[splitedInput[0]].push_back({splitedInput[0], splitedInput[2], stoi(splitedInput[4])});
hashtable[splitedInput[2]].push_back({splitedInput[2], splitedInput[0], stoi(splitedInput[4])});
}
file.close();
return 0;
}
// Fonction de recherche en profondeur (DFS) pour la Partie 1 (distance minimale)
int dfsPart1(Node &n, int minDistance)
{
// Si la distance totale dépasse la distance minimale, on retourne la distance minimale actuelle
if (n.totalDistance > minDistance)
{
return minDistance;
}
// Si toutes les villes ont été visitées, on retourne la distance totale actuelle
if (n.history.size() == hashtable.size())
{
return n.totalDistance;
}
// Parcours des connexions de la ville actuelle
for (CityDistance cd : hashtable[n.actualCity])
{
// Vérification si la ville destination n'a pas déjà été visitée
if (find(n.history.begin(), n.history.end(), cd.to) == n.history.end())
{
// Création d'une copie du nœud actuel avec la nouvelle ville visitée
Node _n = n;
_n.actualCity = cd.to;
_n.totalDistance += cd.distance;
_n.history.push_back(cd.to);
// Appel récursif avec le nouveau nœud
minDistance = min(minDistance, dfsPart1(_n, minDistance));
}
}
return minDistance;
}
// Fonction de traitement pour la Partie 1
int processPart1()
{
MEASURE_FUNCTION_EXECUTION_TIME
int minDistance = INT_MAX;
// Parcours de chaque ville comme point de départ
for (auto &it : hashtable)
{
// Parcours des connexions de chaque ville
for (CityDistance &cd : it.second)
{
Node n = {cd.from, cd.to, cd.distance};
minDistance = dfsPart1(n, minDistance);
}
}
return minDistance;
}
// Fonction de recherche en profondeur (DFS) pour la Partie 2 (distance maximale)
int dfsPart2(Node &n, int maxDistance)
{
// Si toutes les villes ont été visitées
if (n.history.size() == hashtable.size())
{
// on retourne la distance totale si elle est supérieure à la distance maximale
if (n.totalDistance > maxDistance)
{
return n.totalDistance;
}
return maxDistance;
}
// Parcours des connexions de la ville actuelle
for (CityDistance cd : hashtable[n.actualCity])
{
// Vérification si la ville destination n'a pas déjà été visitée
if (find(n.history.begin(), n.history.end(), cd.to) == n.history.end())
{
// Création d'une copie du nœud actuel avec la nouvelle ville visitée
Node _n = n;
_n.actualCity = cd.to;
_n.totalDistance += cd.distance;
_n.history.push_back(cd.to);
// Appel récursif avec le nouveau nœud
maxDistance = max(maxDistance, dfsPart2(_n, maxDistance));
}
}
return maxDistance;
}
// Fonction de traitement pour la Partie 2
int processPart2()
{
MEASURE_FUNCTION_EXECUTION_TIME
int maxDistance = -1;
// Parcours de chaque ville comme point de départ
for (auto &it : hashtable)
{
// Parcours des connexions de chaque ville
for (CityDistance &cd : it.second)
{
Node n = {cd.from, cd.to, cd.distance};
maxDistance = dfsPart2(n, maxDistance);
}
}
return maxDistance;
}
int main()
{
if (parseInput() == 1)
{
return 1;
}
int part1 = processPart1();
int part2 = processPart2();
cout << "\nPart1: " << part1 << '\n';
cout << "Part2: " << part2 << '\n';
return 0;
}