/* Kasioopea 2014 * http://ksp.mff.cuni.cz/akce/kasiopea/ * * Autorské řešení úlohy 26-K-3: Bezpečné království * */ #include #include using namespace std; #define MaxN 2000 #define MaxK 2000 int N, M, K; // Pro město i: // sousede[i] je seznam jeho sousedů // rod[i] je rod strážného města, rod[i] = 0 znamená, že rod ještě nebyl určen vector sousede[MaxN]; int rod[MaxN]; // Pomocné pole pocty[k] udává pro aktuálně zpracovávané město počet sousedních měst se // strážným z rodu k int pocty[MaxK]; int main() { scanf("%d%d%d", &N, &M, &K); for (int i = 0; i < M; i++) { int a, b; scanf("%d%d", &a, &b); sousede[a].push_back(b); sousede[b].push_back(a); } for (int m = 1; m <= N; m++) { for (vector::iterator it = sousede[m].begin(); it != sousede[m].end(); it++) pocty[rod[*it]]++; // Nalezneme rod, ze kterého pochází nejméně sousedů města m, a strážného z tohoto // rodu přidělíme městu m int min_rod = 1; for (int k = 1; k <= K; k++) { if (pocty[k] < pocty[min_rod]) min_rod = k; } // Tento způsob nulování zajistí časovou složitost O(N+M), namísto O(KN + M), // kdybychom pole pocty nulovali celým jeho průchodem for (vector::iterator it = sousede[m].begin(); it != sousede[m].end(); it++) pocty[rod[*it]] = 0; rod[m] = min_rod; } for (int m = 1; m <= N; m++) printf("%d\n", rod[m]); return 0; }