Clasa a XI-a · Metoda backtrackingRead in English
Colorarea hărților în C++
În engleză: Map coloring
Ideea
O hartă are n țări numerotate de la 1, iar m perechi (a, b) spun că țările a și b sunt vecine. Colorăm fiecare țară cu una dintre culorile 1..4 astfel încât două țări vecine să aibă culori diferite. x[k] este culoarea țării k; ea e validă dacă diferă de culorile vecinilor deja colorați (cei cu indice mai mic). Se afișează prima colorare găsită (cea mai mică lexicografic).
Descrierea în engleză
A map has n countries numbered from 1, and m pairs (a, b) say that countries a and b are neighbours. We color every country with one of the colors 1..4 so that two neighbouring countries have different colors. x[k] is the color of country k; it is valid if it differs from the colors of the neighbours already colored (those with a smaller index). The first coloring found (the lexicographically smallest) is printed.
- Complexitate
- O(4^n · n) în cel mai rău caz, de obicei mult mai puțin
- Clasa
- Clasa a XI-a (Grade 11)
- Capitol
- Metoda backtracking
Exemple
Intrare
5 7 1 2 1 3 2 3 2 4 3 4 4 5 3 5
Ieșire așteptată
1 2 3 1 2
Codul C++
Codul complet, cu comentarii în română. Îl poți modifica liber și îl poți reseta oricând.
/*
* Titlu: Colorarea hărților
* Clasa: 11
* Capitol: Metoda backtracking
* Descriere: O hartă are n țări numerotate de la 1, iar m perechi (a, b) spun că țările
* a și b sunt vecine. Colorăm fiecare țară cu una dintre culorile 1..4 astfel
* încât două țări vecine să aibă culori diferite. x[k] este culoarea țării k;
* ea e validă dacă diferă de culorile vecinilor deja colorați (cei cu indice
* mai mic). Se afișează prima colorare găsită (cea mai mică lexicografic).
* Complexitate: O(4^n · n) în cel mai rău caz, de obicei mult mai puțin
*
* Exemplu
* Intrare:
* 5 7
* 1 2
* 1 3
* 2 3
* 2 4
* 3 4
* 4 5
* 3 5
* Ieșire: 1 2 3 1 2
*/
#include <iostream>
using namespace std;
int n, m, x[50];
bool vecin[50][50], gasit = false;
bool valid(int k)
{
for (int i = 1; i < k; i++)
{
if (vecin[i][k] && x[i] == x[k])
{
return false;
}
}
return true;
}
void back(int k)
{
for (int c = 1; c <= 4 && !gasit; c++)
{
x[k] = c;
if (valid(k))
{
if (k == n)
{
gasit = true;
for (int i = 1; i <= n; i++)
{
cout << x[i] << ' ';
}
cout << '\n';
}
else
{
back(k + 1);
}
}
}
}
int main()
{
cin >> n >> m;
for (int i = 1; i <= m; i++)
{
int a, b;
cin >> a >> b;
vecin[a][b] = vecin[b][a] = true;
}
back(1);
if (!gasit)
{
cout << "Nu exista colorare cu 4 culori\n";
}
return 0;
}
Rulează pe un g++ adevărat (C++17, -O2) prin Compiler Explorer. Programele trebuie să se termine repede: există o limită de timp.