Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <queue>
- #include <vector>
- #include <climits>
- using namespace std;
- ///NUMERY KRAWEDZI NA PODSTAWIE KOLEJNOSCI W CIN
- pair<int, int> oddo_kraw[200000+5]; ///dla numeru krawedzi oznacza first -> od, second -> do
- long long waga_kraw[200000+5]; ///dla numeru krawedzi oznacza jego wage
- bool odwiedzone[200000+5];
- bool uzyte_kraw[200000+5]; ///true jak krawedz jest uzyta do mst
- //long long sprawdzone[200000+5]; ///dla krawedzi
- vector<int> krawedzie_z[200000+5]; ///dla poczatkowego grafu okresla numery krawedzi wychodz. z kazdego wierz.
- priority_queue<pair<long long, int> > q; ///kolejka par postaci: -WAGA, NUMER do algo MST
- vector <int> kraw_MST; ///wektor krawedzi do stworzenia drzewa MST
- vector<pair<int, long long> >sasiedzi_MST[200000+5]; ///para sasiad, dlugosc krawedzi
- long long father_MST[200000+5]; ///ojciec wierzch w drzewie MST
- vector<pair<int, long long> > synowie_MST[200000+5]; ///para syn, dl. kraw
- bool odwiedzone_make_MST[200000+5]; ///przydaje sie dla DFS w konstrukcji MST
- int Ancestor_MST[200000+5][20]; ///prawdziwy Ancestor
- long long Ancestor_max_kraw[200000+5][20]; /// niby ancestor - okresla max krawedzie patrzac od wierzcholka x w gore (logarytmicznie)
- int gle[200000+5]; ///glebokosc
- long long n;
- long long m;
- long long wynik1=0;
- long long wynik2= LLONG_MAX;
- void Prim()
- {
- odwiedzone[1] = true;
- ///DODAJEMY DO KOLEJKI WSZYSTKIE KRAWEDZIE WYCHODZACE Z 1
- long long ile_sasiadow = krawedzie_z[1].size();
- for(long long i=0; i<ile_sasiadow; i++)
- {
- long long nr = krawedzie_z[1][i];
- long long w = waga_kraw[nr];
- q.push(make_pair(-w, nr));
- }
- //stan_kolejki();
- while(!q.empty())
- {
- //stan_kolejki();
- long long top_w = -q.top().first;
- long long top_nr = q.top().second;
- q.pop();
- long long A = oddo_kraw[top_nr].first;
- long long B = oddo_kraw[top_nr].second;
- if(odwiedzone[A] == 1 && odwiedzone[B] == 1)
- continue;
- ///A MA BYC DO TEJ PORY NIE ODWIEDZONE
- if(odwiedzone[A] == 1)
- {long long temp=A; A=B; B=temp;}
- kraw_MST.push_back(top_nr);
- odwiedzone[A] = true;
- odwiedzone[B] = true;
- long long ile_sas = krawedzie_z[A].size();
- for(long long i=0; i<ile_sas; i++)
- {
- long long nr_kraw = krawedzie_z[A][i];
- long long waga = waga_kraw[nr_kraw];
- q.push(make_pair(-waga, nr_kraw));
- }
- }
- }
- void DFS_make_MST(long long w)
- {
- if(odwiedzone_make_MST[w] == 1)
- return;
- odwiedzone_make_MST[w] = 1;
- Ancestor_max_kraw[1][0] = 0;
- long long ojciec = father_MST[w];
- long long ile_sas = sasiedzi_MST[w].size();
- for(long long i=0; i<ile_sas; i++)
- {
- if(sasiedzi_MST[w][i].first != ojciec)
- {
- father_MST[sasiedzi_MST[w][i].first] = w;
- synowie_MST[w].push_back(make_pair(sasiedzi_MST[w][i].first, sasiedzi_MST[w][i].second));
- Ancestor_max_kraw[sasiedzi_MST[w][i].first][0] = sasiedzi_MST[w][i].second;
- DFS_make_MST(sasiedzi_MST[w][i].first);
- }
- }
- }
- void make_MST()
- {
- ///1.TABLICA SASIADOW
- long long ile_kraw = kraw_MST.size();
- for(long long i=0; i<ile_kraw; i++)
- {
- long long od_k = oddo_kraw[kraw_MST[i]].first;
- long long do_k = oddo_kraw[kraw_MST[i]].second;
- long long waga_k = waga_kraw[kraw_MST[i]];
- sasiedzi_MST[od_k].push_back(make_pair(do_k, waga_k));
- sasiedzi_MST[do_k].push_back(make_pair(od_k, waga_k));
- }
- father_MST[1] = 1;
- ///2. TABLICA OJCOW I VECTOR SYNOW
- DFS_make_MST(1);
- }
- void make_Ancestors()
- {
- for(long long i=1; i<=n; i++)
- Ancestor_MST[i][0] = father_MST[i];
- for(long long k=1; k<=18; k++)
- for(long long x=1; x<=n; x++)
- Ancestor_MST[x][k] = Ancestor_MST[Ancestor_MST[x][k-1]][k-1];
- }
- long long make_Gle(long long w)
- {
- if(gle[w] != -1)
- return gle[w];
- gle[w] = make_Gle(father_MST[w]) + 1;
- return gle[w];
- }
- long long find_B_prim(long long A, long long B)
- {
- for(long long k=18; k>=0; k--)
- if(gle[Ancestor_MST[B][k]] >= gle[A])
- B = Ancestor_MST[B][k];
- return B;
- }
- long long LCA(long long A, long long B)
- {
- //cout<<"A: "<<A<<" B: "<<B;
- if(gle[A] > gle[B])
- {long long temp=A; A=B; B=temp;}
- long long B_prim = find_B_prim(A, B);
- if(B_prim == A)
- //cout<<" LCA: "<<A<<endl;
- {return A;}
- else
- {
- B=B_prim;
- for(long long k=18; k>=0; k--)
- if(Ancestor_MST[A][k] != Ancestor_MST[B][k])
- {
- A = Ancestor_MST[A][k];
- B = Ancestor_MST[B][k];
- }
- //cout<<" LCA: "<<father_MST[A]<<endl;
- return father_MST[A];
- }
- }
- void make_ANC_max_Kraw()
- {
- Ancestor_max_kraw[1][0] = 0;
- ///DLA STOPNIA 0 SCIEZKA KTORA LACZY WIERZCHOLEK Z JEGO OJCEM (gotowe wczesniej)
- for(long long k=1; k<=18; k++)
- for(long long x=1; x<=n; x++)
- Ancestor_max_kraw[x][k] = max(Ancestor_max_kraw[x][k-1], Ancestor_max_kraw[Ancestor_MST[x][k-1]][k-1]);
- }
- long long max_Kraw(long long A, long long B)
- {
- //cout<<"SZUKAM MAX_KRAW NA SCIEZCE OD: "<<A<<" DO: "<<B<<endl;
- long long LCA_AB = LCA(A,B);
- //cout<<"LCA: "<<LCA_AB<<endl;
- long long max_k = 0;
- ///CZ 1 OD A DO LCA
- for(long long k=18; k>=0; k--)
- {
- if(gle[LCA_AB] <= gle[Ancestor_MST[A][k]])
- {
- //cout<<"KANDYDAT: "<<Ancestor_max_kraw[A][k]<<endl;
- max_k = max(max_k, Ancestor_max_kraw[A][k]);
- A = Ancestor_MST[A][k];
- }
- }
- ///CZ 2 OD B DO LCA
- for(long long k=18; k>=0; k--)
- {
- if(gle[LCA_AB] <= gle[Ancestor_MST[B][k]])
- {
- //cout<<"KANDYDAT: "<<Ancestor_max_kraw[B][k]<<endl;
- max_k = max(max_k, Ancestor_max_kraw[B][k]);
- B = Ancestor_MST[B][k];
- }
- }
- //cout<<endl;
- return max_k;
- }
- int main()
- {
- cin>>n;
- cin>>m;
- long long t1;
- long long t2;
- long long t3;
- for(long long i=1; i<=m; i++)
- {
- cin>>t1;
- cin>>t2;
- cin>>t3;
- oddo_kraw[i] = make_pair(t1, t2);
- waga_kraw[i] = t3;
- krawedzie_z[t1].push_back(i);
- krawedzie_z[t2].push_back(i);
- }
- Prim();
- wynik1 = 0;
- long long ile_uz_kraw = kraw_MST.size();
- for(long long i=0; i<ile_uz_kraw; i++)
- {
- uzyte_kraw[kraw_MST[i]] = true;
- wynik1 += waga_kraw[kraw_MST[i]];
- }
- //cout<<"wynik1: "<<wynik1<<endl;
- make_MST();
- gle[1] = 0;
- for(long long i=2; i<=n; i++)
- gle[i] = -1;
- for(long long i=2; i<=n; i++)
- make_Gle(i);
- //cout<<"GLE"<<endl;
- // for(long long i=1; i<=n; i++)
- /* cout<<gle[i]<<endl;
- cout<<endl;
- cout<<"OJCOWIE: "<<endl;
- for(long long i=1; i<=n; i++)
- cout<<i<<": "<<father_MST[i]<<endl;
- ///DOTAD OK
- */
- ///FUNKCJA LCA
- //a)ANCESTORS
- make_Ancestors();
- /* cout<<"ANCESTORS"<<endl;
- for(long long i=1; i<=n; i++)
- {
- for(long long k=0; k<=4; k++)
- cout<<Ancestor_MST[i][k]<<'\t';
- cout<<endl;
- //cout<<"LCA: "<<LCA_AB<<endl;
- //cout<<"PREORDER"<<endl;
- //cout<<"A: "<<preorder[A]<<" B: "<<preorder[B]<<" LCA: "<<preorder[LCA_AB]<<endl;
- }*/
- //b) LCA + B_prim
- make_ANC_max_Kraw();
- /* cout<<"ANCESTORS_MK"<<endl;
- for(long long i=1; i<=n; i++)
- {
- for(long long k=0; k<=4; k++)
- cout<<Ancestor_max_kraw[i][k]<<'\t';
- cout<<endl;
- }*/
- for(long long i=1; i<=m; i++)
- {
- if(uzyte_kraw[i] == false)
- {
- //cout<<"ROZPATRUJE UZYCIE KRAWEDZI: "<<oddo_kraw[i].first<<" "<<oddo_kraw[i].second<<" jej waga: "<<waga_kraw[i]<<endl;
- long long waga = waga_kraw[i];
- long long max_k = max_Kraw(oddo_kraw[i].first, oddo_kraw[i].second);
- long long kandydat_na_w2 = wynik1 - max_k + waga;
- //cout<<"WYNIK OSTATECZNEGO KANDYDTA W TEJ SCIEZCE: "<<kandydat_na_w2<<endl;
- wynik2 = min(wynik2, kandydat_na_w2);
- }
- }
- cout<<wynik2;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement