Submission #512832

#TimeUsernameProblemLanguageResultExecution timeMemory
512832MathMateGame (IOI14_game)C++17
100 / 100
337 ms19344 KiB
// #include <game.h> #include <bits/stdc++.h> using namespace std; const int MAX_N = 1.5e3 + 5; // graf_ustawionych -> graf krawedzi ustawionych i przyjmuje, ze mozliwe nie sa ustawione // graf_ustawionych_i_mozliwych -> graf krawedzi ustawionych i przyjmuje, ze mozliwe tez sa ustawione // Na poczatku ma wszystkie krawedzie sa nieustawione w grafie graf_ustawionych // Na poczatku ma wszystkie krawedzie sa ustawione w grafie graf_ustawionych_i_mozliwych // Na zapytanie o to czy {a, b} sa polaczone: // * "YES" -> gdy {a, b} jest mostem w grafie_ustawionych_i_mozliwych // * "NO" -> w przeciwnym przypadku // Czyli innymi slowy odpowiadamy: // * "YES" -> w przeciwnym przypadku // * "NO" -> gdy {a, b} nalezy do cyklu w grafie_ustawionych_i_mozliwych // Zeby rozwiazac to szybciej niz w O(MAX_N ^ 4) -> czyli w O(MAX_N ^ 2) // Do znajdowania mostow posluzymy sie struktura F & U (DSU) // I tablice ilosc_krawedzi_laczacych_wierzcholki[a][b], ktora bedzie mowila nam // Ile krawedzi laczy find_set(a) z find_set(b) // Krawedz {a, b} bedzie mostem w grafie_ustawionych_i_mozliwych, // Jesli ilosc_krawedzi_laczacych_wierzcholki[a][b] == 1 // union_sets() zajmuje O(n), a find_set() zajmuje O(1) // Poczatkowo ilosc_krawedzi_laczacych_wierzcholki[a][b] == 1 dla kazdej pary {a, b}, // Gdzie a != b // Jesli odpowiadamy "NO", to zmniejszamy ilosc_krawedzi_laczacych_wierzcholki[a][b] i ilosc_krawedzi_laczacych_wierzcholki[b][a] o 1 // Jesli odpowiadamy "YES", to dla kazdego reprezentanta i, // Robimy ilosc_krawedzi_laczacych_wierzcholki[a][i] += ilosc_krawedzi_laczacych_wierzcholki[b][i] // Operacji union_set() moze byc maksymalnie (n - 1), wiec wszystkie operacje union_set() to O(MAX_N ^ 2) // Update ilosc_krawedzi_laczacych_wierzcholki[a][b] w przypadku "YES", to O(n), ale operacji update wykonamy maksymalnie (n - 1), wiec wszystkie updaty to O(MAX_N ^ 2) // Calkowita zlozonosc: O(MAX_N ^ 2) int ilosc_krawedzi_laczacych_wierzcholki[MAX_N][MAX_N]; vector <int> rodzic(MAX_N); int n; int find_set(int v) { if(v == rodzic[v]) { return v; } return rodzic[v] = find_set(rodzic[v]); } void make_set(int v) { rodzic[v] = v; } void union_sets(int a, int b) { a = find_set(a); b = find_set(b); for(int i = 0; i < n; i++) { int reprezentant_i = find_set(i); if(reprezentant_i == i) { ilosc_krawedzi_laczacych_wierzcholki[a][i] += ilosc_krawedzi_laczacych_wierzcholki[b][i]; ilosc_krawedzi_laczacych_wierzcholki[i][a] = ilosc_krawedzi_laczacych_wierzcholki[a][i]; } } rodzic[b] = a; } bool check(int a, int b) { return find_set(a) == find_set(b); } void initialize(int ilosc_wierzcholkow) { n = ilosc_wierzcholkow; for(int i = 0; i < n; i++) { make_set(i); } for(int i = 0; i < n; i++) { for(int j = i + 1; j < n; j++) { ilosc_krawedzi_laczacych_wierzcholki[i][j] = (i != j); ilosc_krawedzi_laczacych_wierzcholki[j][i] = (i != j); } } } int hasEdge(int a, int b) { a = find_set(a); b = find_set(b); if(a == b) { return 0; } bool ok = (ilosc_krawedzi_laczacych_wierzcholki[a][b] == 1); if(ok) { union_sets(a, b); } else { ilosc_krawedzi_laczacych_wierzcholki[a][b]--; ilosc_krawedzi_laczacych_wierzcholki[b][a]--; } return ok; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...