Advertisement
Guest User

Untitled

a guest
Jul 21st, 2019
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.35 KB | None | 0 0
  1. #include <iostream>
  2. #include <queue>
  3. #include <vector>
  4. #include <climits>
  5. using namespace std;
  6.  
  7.  
  8. ///NUMERY KRAWEDZI NA PODSTAWIE KOLEJNOSCI W CIN
  9. pair<int, int> oddo_kraw[200000+5]; ///dla numeru krawedzi oznacza first -> od, second -> do
  10. long long waga_kraw[200000+5]; ///dla numeru krawedzi oznacza jego wage
  11. bool odwiedzone[200000+5];
  12. bool uzyte_kraw[200000+5]; ///true jak krawedz jest uzyta do mst
  13. //long long sprawdzone[200000+5]; ///dla krawedzi
  14.  
  15. vector<int> krawedzie_z[200000+5]; ///dla poczatkowego grafu okresla numery krawedzi wychodz. z kazdego wierz.
  16. priority_queue<pair<long long, int> > q; ///kolejka par postaci: -WAGA, NUMER do algo MST
  17.  
  18. vector <int> kraw_MST; ///wektor krawedzi do stworzenia drzewa MST
  19. vector<pair<int, long long> >sasiedzi_MST[200000+5]; ///para sasiad, dlugosc krawedzi
  20. long long father_MST[200000+5]; ///ojciec wierzch w drzewie MST
  21. vector<pair<int, long long> > synowie_MST[200000+5]; ///para syn, dl. kraw
  22. bool odwiedzone_make_MST[200000+5]; ///przydaje sie dla DFS  w konstrukcji MST
  23. int Ancestor_MST[200000+5][20]; ///prawdziwy Ancestor
  24. long long Ancestor_max_kraw[200000+5][20]; /// niby ancestor - okresla max krawedzie patrzac od wierzcholka x w gore (logarytmicznie)
  25.  
  26. int gle[200000+5]; ///glebokosc
  27.  
  28. long long n;
  29. long long m;
  30. long long wynik1=0;
  31. long long wynik2= LLONG_MAX;
  32.  
  33. void Prim()
  34. {
  35.     odwiedzone[1] = true;
  36.     ///DODAJEMY DO KOLEJKI WSZYSTKIE KRAWEDZIE WYCHODZACE Z 1
  37.     long long ile_sasiadow = krawedzie_z[1].size();
  38.     for(long long i=0; i<ile_sasiadow; i++)
  39.     {
  40.         long long nr = krawedzie_z[1][i];
  41.         long long w = waga_kraw[nr];
  42.         q.push(make_pair(-w, nr));
  43.     }
  44.  
  45.    //stan_kolejki();
  46.  
  47.  
  48.     while(!q.empty())
  49.     {
  50.         //stan_kolejki();
  51.         long long top_w = -q.top().first;
  52.         long long top_nr = q.top().second;
  53.  
  54.         q.pop();
  55.  
  56.         long long A = oddo_kraw[top_nr].first;
  57.         long long B = oddo_kraw[top_nr].second;
  58.  
  59.         if(odwiedzone[A] == 1 && odwiedzone[B] == 1)
  60.             continue;
  61.  
  62.         ///A MA BYC DO TEJ PORY NIE ODWIEDZONE
  63.         if(odwiedzone[A] == 1)
  64.         {long long temp=A; A=B; B=temp;}
  65.  
  66.  
  67.         kraw_MST.push_back(top_nr);
  68.         odwiedzone[A] = true;
  69.         odwiedzone[B] = true;
  70.  
  71.         long long ile_sas = krawedzie_z[A].size();
  72.         for(long long i=0; i<ile_sas; i++)
  73.         {
  74.             long long nr_kraw = krawedzie_z[A][i];
  75.             long long waga = waga_kraw[nr_kraw];
  76.             q.push(make_pair(-waga, nr_kraw));
  77.         }
  78.     }
  79. }
  80.  
  81. void DFS_make_MST(long long w)
  82. {
  83.     if(odwiedzone_make_MST[w] == 1)
  84.         return;
  85.  
  86.     odwiedzone_make_MST[w] = 1;
  87.     Ancestor_max_kraw[1][0] = 0;
  88.  
  89.     long long ojciec = father_MST[w];
  90.     long long ile_sas = sasiedzi_MST[w].size();
  91.  
  92.     for(long long i=0; i<ile_sas; i++)
  93.     {
  94.         if(sasiedzi_MST[w][i].first != ojciec)
  95.         {
  96.             father_MST[sasiedzi_MST[w][i].first] = w;
  97.             synowie_MST[w].push_back(make_pair(sasiedzi_MST[w][i].first, sasiedzi_MST[w][i].second));
  98.  
  99.             Ancestor_max_kraw[sasiedzi_MST[w][i].first][0] = sasiedzi_MST[w][i].second;
  100.  
  101.             DFS_make_MST(sasiedzi_MST[w][i].first);
  102.         }
  103.     }
  104. }
  105.  
  106. void make_MST()
  107. {
  108.     ///1.TABLICA SASIADOW
  109.     long long ile_kraw = kraw_MST.size();
  110.  
  111.     for(long long i=0; i<ile_kraw; i++)
  112.     {
  113.         long long od_k = oddo_kraw[kraw_MST[i]].first;
  114.         long long do_k = oddo_kraw[kraw_MST[i]].second;
  115.         long long waga_k = waga_kraw[kraw_MST[i]];
  116.  
  117.         sasiedzi_MST[od_k].push_back(make_pair(do_k, waga_k));
  118.         sasiedzi_MST[do_k].push_back(make_pair(od_k, waga_k));
  119.     }
  120.  
  121.     father_MST[1] = 1;
  122.     ///2. TABLICA OJCOW I VECTOR SYNOW
  123.     DFS_make_MST(1);
  124. }
  125.  
  126. void make_Ancestors()
  127. {
  128.     for(long long i=1; i<=n; i++)
  129.         Ancestor_MST[i][0] = father_MST[i];
  130.     for(long long k=1; k<=18; k++)
  131.         for(long long x=1; x<=n; x++)
  132.              Ancestor_MST[x][k] = Ancestor_MST[Ancestor_MST[x][k-1]][k-1];
  133. }
  134.  
  135. long long make_Gle(long long w)
  136. {
  137.     if(gle[w] != -1)
  138.         return gle[w];
  139.  
  140.     gle[w] = make_Gle(father_MST[w]) + 1;
  141.     return gle[w];
  142. }
  143.  
  144. long long find_B_prim(long long A, long long B)
  145. {
  146.     for(long long k=18; k>=0; k--)
  147.         if(gle[Ancestor_MST[B][k]] >= gle[A])
  148.             B = Ancestor_MST[B][k];
  149.  
  150.     return B;
  151.  
  152. }
  153.  
  154. long long LCA(long long A, long long B)
  155. {
  156.     //cout<<"A: "<<A<<" B: "<<B;
  157.     if(gle[A] > gle[B])
  158.     {long long temp=A; A=B; B=temp;}
  159.  
  160.     long long B_prim = find_B_prim(A, B);
  161.  
  162.     if(B_prim == A)
  163.         //cout<<" LCA: "<<A<<endl;
  164.         {return A;}
  165.  
  166.     else
  167.     {
  168.         B=B_prim;
  169.         for(long long k=18; k>=0; k--)
  170.             if(Ancestor_MST[A][k] != Ancestor_MST[B][k])
  171.             {
  172.                 A = Ancestor_MST[A][k];
  173.                 B = Ancestor_MST[B][k];
  174.             }
  175.  
  176.         //cout<<" LCA: "<<father_MST[A]<<endl;
  177.         return father_MST[A];
  178.  
  179.     }
  180. }
  181.  
  182. void make_ANC_max_Kraw()
  183. {
  184.     Ancestor_max_kraw[1][0] = 0;
  185.     ///DLA STOPNIA 0 SCIEZKA KTORA LACZY WIERZCHOLEK Z JEGO OJCEM (gotowe wczesniej)
  186.  
  187.     for(long long k=1; k<=18; k++)
  188.         for(long long x=1; x<=n; x++)
  189.              Ancestor_max_kraw[x][k] = max(Ancestor_max_kraw[x][k-1], Ancestor_max_kraw[Ancestor_MST[x][k-1]][k-1]);
  190. }
  191.  
  192. long long max_Kraw(long long A, long long B)
  193. {
  194.     //cout<<"SZUKAM MAX_KRAW NA SCIEZCE OD: "<<A<<" DO: "<<B<<endl;
  195.     long long LCA_AB = LCA(A,B);
  196.     //cout<<"LCA: "<<LCA_AB<<endl;
  197.  
  198.     long long max_k = 0;
  199.     ///CZ 1 OD A DO LCA
  200.     for(long long k=18; k>=0; k--)
  201.     {
  202.         if(gle[LCA_AB] <= gle[Ancestor_MST[A][k]])
  203.         {
  204.             //cout<<"KANDYDAT: "<<Ancestor_max_kraw[A][k]<<endl;
  205.             max_k = max(max_k, Ancestor_max_kraw[A][k]);
  206.             A = Ancestor_MST[A][k];
  207.         }
  208.     }
  209.  
  210.     ///CZ 2 OD B DO LCA
  211.     for(long long k=18; k>=0; k--)
  212.     {
  213.         if(gle[LCA_AB] <= gle[Ancestor_MST[B][k]])
  214.         {
  215.             //cout<<"KANDYDAT: "<<Ancestor_max_kraw[B][k]<<endl;
  216.             max_k = max(max_k, Ancestor_max_kraw[B][k]);
  217.             B = Ancestor_MST[B][k];
  218.         }
  219.     }
  220.     //cout<<endl;
  221.     return max_k;
  222. }
  223.  
  224.  
  225. int main()
  226. {
  227.     cin>>n;
  228.     cin>>m;
  229.  
  230.     long long t1;
  231.     long long t2;
  232.     long long t3;
  233.     for(long long i=1; i<=m; i++)
  234.     {
  235.         cin>>t1;
  236.         cin>>t2;
  237.         cin>>t3;
  238.  
  239.         oddo_kraw[i] = make_pair(t1, t2);
  240.         waga_kraw[i] = t3;
  241.  
  242.         krawedzie_z[t1].push_back(i);
  243.         krawedzie_z[t2].push_back(i);
  244.     }
  245.  
  246.     Prim();
  247.  
  248.     wynik1 = 0;
  249.  
  250.     long long ile_uz_kraw = kraw_MST.size();
  251.     for(long long i=0; i<ile_uz_kraw; i++)
  252.     {
  253.         uzyte_kraw[kraw_MST[i]] = true;
  254.         wynik1 += waga_kraw[kraw_MST[i]];
  255.  
  256.     }
  257.     //cout<<"wynik1: "<<wynik1<<endl;
  258.  
  259.     make_MST();
  260.  
  261.  
  262.     gle[1] = 0;
  263.     for(long long i=2; i<=n; i++)
  264.         gle[i] = -1;
  265.  
  266.     for(long long i=2; i<=n; i++)
  267.         make_Gle(i);
  268.  
  269.     //cout<<"GLE"<<endl;
  270.   //  for(long long i=1; i<=n; i++)
  271.    /*     cout<<gle[i]<<endl;
  272.  
  273.     cout<<endl;
  274.  
  275.     cout<<"OJCOWIE: "<<endl;
  276.     for(long long i=1; i<=n; i++)
  277.         cout<<i<<": "<<father_MST[i]<<endl;
  278.     ///DOTAD OK
  279. */
  280.     ///FUNKCJA LCA
  281.     //a)ANCESTORS
  282.     make_Ancestors();
  283.    /* cout<<"ANCESTORS"<<endl;
  284.     for(long long i=1; i<=n; i++)
  285.     {
  286.         for(long long k=0; k<=4; k++)
  287.             cout<<Ancestor_MST[i][k]<<'\t';
  288.         cout<<endl;
  289.  
  290.         //cout<<"LCA: "<<LCA_AB<<endl;
  291.             //cout<<"PREORDER"<<endl;
  292.             //cout<<"A: "<<preorder[A]<<" B: "<<preorder[B]<<" LCA: "<<preorder[LCA_AB]<<endl;
  293.  
  294.     }*/
  295.  
  296.     //b) LCA + B_prim
  297.  
  298.     make_ANC_max_Kraw();
  299.    /* cout<<"ANCESTORS_MK"<<endl;
  300.     for(long long i=1; i<=n; i++)
  301.     {
  302.         for(long long k=0; k<=4; k++)
  303.             cout<<Ancestor_max_kraw[i][k]<<'\t';
  304.         cout<<endl;
  305.     }*/
  306.  
  307.  
  308.  
  309.     for(long long i=1; i<=m; i++)
  310.     {
  311.         if(uzyte_kraw[i] == false)
  312.         {
  313.             //cout<<"ROZPATRUJE UZYCIE KRAWEDZI: "<<oddo_kraw[i].first<<" "<<oddo_kraw[i].second<<" jej waga: "<<waga_kraw[i]<<endl;
  314.             long long waga = waga_kraw[i];
  315.             long long max_k = max_Kraw(oddo_kraw[i].first, oddo_kraw[i].second);
  316.             long long kandydat_na_w2 = wynik1 - max_k + waga;
  317.             //cout<<"WYNIK OSTATECZNEGO KANDYDTA W TEJ SCIEZCE: "<<kandydat_na_w2<<endl;
  318.             wynik2 = min(wynik2, kandydat_na_w2);
  319.         }
  320.     }
  321.     cout<<wynik2;
  322.     return 0;
  323. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement