6 - Parovi
Vremensko ograničenje | Memorijsko ograničenje |
---|---|
1000ms | 64MB |
Dat je povezan neusmeren težinski graf od \(N\) čvorova i \(M\) grana, i prirodan broj \(K\). Grane su numerisane od \(1\) do \(M\), gde \(i\)-ta grana ima težinu \(\lceil \frac{i}{K} \rceil\).
Označimo sa \(f(x, y)\), gde je \(1 \leq x < y \leq N\), odgovor na sledeći upit:
- Među svim minimalnim razapinjućim stablima datog grafa, naći ono sa najvećom vrednosti zbira stepena čvorova \(x\) i \(y\), i vratiti tu vrednost.
Izračunajte \(\sum\limits_{x=1}^N \sum\limits_{y=x+1}^N f(x, y)\), tj. sumu vrednosti \(f(x, y)\) za sve \(1 \leq x < y \leq N\).
Opisi funkcija
Potrebno je da implementirate funkciju
- \(Resi(N, M, K, U[\dots], V[\dots])\)
Funkcija \(Resi\) se poziva samo jednom na početku ivršavanja programa, a njeni parametri su:
- \(N\): broj čvorova u grafu.
- \(M\): broj grana u grafu.
- \(K\): parametar koji označava da \(i\)-ta grana ima težinu \(\lceil \frac{i}{K} \rceil\).
- \(U[\dots]\), \(V[\dots]\): nizovi dužine \(M\), indeksirani od 1, koji opisuju grane: \(i\)-ta grana spaja čvorove \(U_i\) i \(V_i\).
Funkcija \(Resi\) treba da vrati jedan ceo broj - vrednost \(\sum\limits_{x=1}^N \sum\limits_{y=x+1}^N f(x, y)\).
Primer
Neka je \(N=4\), \(M=4\), \(K=2\), \(U = [1, 3, 4, 2]\), \(V = [2, 4, 1, 3]\). U ovom grafu su grane \(1-2\) i \(3-4\) težine \(1\), a grane \(4-1\) i \(2-3\) težine \(2\). Ovaj graf ima dva moguća minimalna razapinjuća stabla - jedno sa granama \(1-2\), \(3-4\) i \(1 - 4\), drugo sa granama \(1 - 2\), \(3 - 4\), \(2 - 3\).
U prvom stablu čvorovi \(1\) i \(4\) imaju stepen \(2\), a \(2\) i \(3\) stepen \(1\). U drugom stablu čvorovi \(1\) i \(4\) imaju stepen \(1\), a \(2\) i \(3\) stepen \(2\). Ako za svaki par uzmemo bolje od data dva stabla, dobijamo vrednosti \(f(1, 2) = 3\), \(f(1, 3) = 3\), \(f(1, 4) = 4\), \(f(2, 3) = 4\), \(f(2, 4) = 3\), \(f(3, 4) = 3\), pa je broj koji funkcija \(Resi\) treba da vrati jednak \(3+3+4+4+3+3=20\).
Ograničenja
- \(1 \leq N \leq 100.000\)
- \(1 \leq M \leq 200.000\)
- \(1 \leq K \leq 100\)
- \(1 \leq u_i, v_i \leq N\) i \(u_i \neq v_i\) za \(1 \leq i \leq M\)
- Dati graf je povezan.
Podzadaci
- [5 poena]: \(M \leq 18\)
- [11 poena]: \(N \leq 50, M = K\)
- [12 poena]: \(N \leq 100, M \leq 200\)
- [14 poena]: \(K \leq 6\)
- [16 poena]: \(N \leq 1.000, M \leq 2.000\)
- [42 poena]: Bez dodatnih ograničenja
Detalji implementacije
Potrebno je da pošaljete tačno jedan fajl parovi.cpp
koji implementira pomenutu funkciju. Osim traženih funkcija, vaš fajl može sadržati i dodatne globalne promenljive, pomoćne funkcije i dodatne biblioteke.
Vaša funkcija mora biti sledećeg oblika:
long long Resi(int N, int M, int K, int* U, int* V);
Vašim programima je dozvoljeno da menjaju sadržaj nizova ali ne smeju da pristupaju van granica datih nizova.
Uz zadatak, obezbeđen vam je "template" fajl code.cpp
koje možete koristiti i menjati po potrebi. Takođe vam je obezbeđen program grader.cpp
koji služi da lakše testirate kodove. Ovaj program učitava sa standardnog ulaza sledeće podatke:
- U prvom redu brojevi \(N\), \(M\) i \(K\).
- U narednih \(M\) redova brojevi \(A_i\) i \(B_i\).
Zatim ovaj program zove vašu funkciju i ispisuje rezultate koje ona vrati.
Napomena
Razapinjuće stablo povezanog težinskog neusmerenog grafa je težinsko stablo (povezan acikličan neusmeren graf) koje sadrži sve čvorove i čije se sve grane sadrže i u početnom grafu.
Minimalno razapinjuće stablo je bilo koje razapinjuće stablo sa minimalnom sumom težina grana.
Autor | Tekst i test primeri | Analiza rеšenja | Testiranje |
---|---|---|---|
Jovan Bengin | Jovan Bengin | Momčilo Tošić | Jovan Bengin |
Rešenje kad \(M \leq 18\)
U ovom slučaju možemo isprobati svako razapinjujuće stablo (biranjem svakog podskupa grana), naći sva minimalna i za svaki par čvorova (kojih isto ima malo jer je graf povezan) naći i dodati rešenje. Tada je složenost \(O(N^2 2^M)\)
Rešenje kad \(M = K, N \leq 50\)
Uočimo da će težina svake grane biti 1. Dakle, MST je svako razapinjujuće stablo, a kako je i broj čvorova manji, možemo da izračunamo rešenje za svaki par na tzv. pohlepan način. Ovde je potrebno uraditi analizu slučajeva, prebrojimo sve čvorove sa direktnim vezama do ona dva koje posmatramo, oduzimajući one koji su zajednički (s tim da se s jednim mogu oba povezati ukoliko ne postoji grana između njih). Složenost će biti \(O(N^2(N+M))\).
Rešenje kad je \(N \leq 100, M \leq 200\)
Možemo ponovo rešavati za svaka dva čvora, s tim što puštamo simulaciju nalaženja MST sa optimalnim biranjem grana tako da se maksimizuju one koje uključuju neki od dva odabrana čvora. Složenost je u ovom slučaju \(O(N^2 M\log{M})\).
Rešenje kad \(K \leq 6\)
Za ovo rešenje potrebno je preći na drugačiji način prebrojavanja (koji se koristi i u celon rešenju) - grupišemo grane sa jednakim težinama (kažemo da je čvor u grupi ako postoji grana u grupi koja ga sadrži) i brojimo koliko puta grane iz date grupe "figurišu" u konačnom zbiru (dakle bar jedan od selektovanih čvorova je neki iz grupe). Pošto Kruskalov algoritam dodaje grane u sortiranom redosledu, možemo računati da kada posmatramo grupu težine \(W\) su čvorovi već povezani u komponente koje formiraju grane težina ispod \(W\). Da bi se formirao MST svakako se u njega dodaje neki podskup novih grana, a kako je broj \(K\) mali, možemo ručno probati svaki podskup i videti koliko grane doprinose zbiru (za svaka dva čvora koja se pojavljuju u grupi kao krajevi veza). Kako ima \(\frac{M}{K}\) grupa, a \(O(K)\) i čvorova i grana u grupi, složenost je \(O(2^K MK)\).
Rešenje za pun broj poena
Moguće je izvršiti prebrojavanje pojavljivanja grana u maks stepeninma čvorova iz grupe i brže, tako da ne postoji dodatni faktor osim kvadratnog po \(K\). Posmatrajmo veze čvorova iz grupe sa već formiranim komponentama. Fiksiramo 2 čvora u grupi i za njih dodajemo broj komponenti s kojima su povezani, oduzimajući broj s kojim su oba povezana, sa obraćanjem pažnje na specijalne slučajeve (neki od dva čvora povezan je sa komponentom od ovog drugog, u istoj su komponenti, ili postoji direktna veza između dva selektovana čvora). Ovde se radi nešto donekle slično kao u drugom podzadatku, s tim što je (uslovno rečeno) tada jedina grupa bio skup svih čvorova, sada treba dodati i doprinos grana u trenutnoj grupi na zbir stepena kad selektovan par uključuje jedan čvor koji se ne pojavljuje u grupi, mada ovo se računa samo kao broj komponenti s kojim je povezan onaj čvor koji jeste u grupi (naravno onoliko puta koliko ima čvorova van grupe). Nakon ovog procesa, ažuriramo komponente i prelazimo na narednu grupu. Ukupna složenost je (istim rezonom kao i pre) \(O(MK)\).
06_parovi.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 |
|