Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #include <vector>
- #include <cmath>
- #include <algorithm>
- using namespace std;
- struct nodeUF
- {
- int parent; // koe e parent na temeto
- int tree_size; // koe e nivoto na drvoto vo koe sho se naogja ova teme
- };
- struct rebroQ
- {
- int idx1; // pocetno teme
- int idx2; // krajno teme
- double weight; // tezina na rebroto
- };
- class UF // UnionFind
- {
- vector<nodeUF> teminja; // nizata kade shto chuvame koe teme e parent na koe vo format teminja[a] = b, kade shto b e parent na a
- public:
- UF(int n)
- {
- for(int i = 0; i < n; i++)
- teminja.push_back({i, 1}); // na pochetokot gi inicijalizirame site teminja da se parent na sebesi
- }
- inline bool is_connected(int id1, int id2) // proveri dali dve teminja se vo ist cluster, taka shto kje gi sporedish roots na drvata vo koe shto se naogjaat dvete teminja soodvetno
- {
- return(find_root(id1) == find_root(id2));
- }
- int find_root(int idx) // najdi root na drvoto vo koe shto se naogja temeto
- {
- int curr = idx;
- while(teminja[curr].parent != curr) // se dodeka nekoe teme ne e parent na sebesi
- {
- teminja[curr].parent = teminja[teminja[curr].parent].parent; // parentot na momentalnoto teme e parentot na negoviot parent (optimizacija za vreme, i bez ova raboti tochno no znacitelno pobavno)
- curr = teminja[curr].parent; // novoto teme za razgleduvanje e parentot
- }
- return(curr); // vrati go poslednoto teme shto sum go proveril (toa shto e parent na samoto sebesi)
- }
- void merge_trees(int id1, int id2) // spoi dve teminja (t.e drva)
- {
- int prv, vtor;
- prv = find_root(id1);
- vtor = find_root(id2); // najdi gi roots na dvete teminja
- //vidi koe drvo e pomalo, i toa spoi go na pogolemoto, nivoto na drvoto ostanuva isto
- if(teminja[prv].tree_size < teminja[vtor].tree_size)
- teminja[prv].parent = teminja[vtor].parent;
- else if(teminja[prv].tree_size > teminja[vtor].tree_size)
- teminja[vtor].parent = teminja[prv].parent;
- else // dokolku se isti, spoi koe bilo na koe bilo, no nivoto na novoto drvo se zgolemuva za 1
- {
- teminja[vtor].parent = teminja[prv].parent;
- teminja[prv].tree_size += 1;
- }
- return;
- }
- };
- bool sporedi(rebroQ a, rebroQ b) // komparator za da raboti sort funkcijata
- {
- if(a.weight == b.weight)
- {
- if(a.idx1 == b.idx1)
- return(a.idx2 < b.idx2);
- return(a.idx1 < b.idx1);
- }
- return(a.weight < b.weight);
- }
- int main()
- {
- ios_base::sync_with_stdio(false);
- int n, m; // broj na teminja i broj na rebra
- int n_found = 0; // broj na teminja staveni
- int t1, t2, td; // momentalni promenlivi
- cin >> n >> m;
- int MIN=1000000000;
- vector<rebroQ> edges(m);
- for(int i = 0; i < m; i++)
- {
- cin >> edges[i].idx1 >> edges[i].idx2 >> edges[i].weight; // chitanje na rebra
- edges[i].idx1--;
- edges[i].idx2--;
- }
- UF cluster(n);
- sort(edges.begin(), edges.end(), sporedi); // sortiranje na rebra
- int izlez = 0;
- int zbir=0;
- vector<bool> nov(m),nov1(m);
- nov.assign(m,false);
- nov1.assign(m,false);
- for(int i = 0; i < m && n_found < n; i++)
- {
- t1 = edges[i].idx1;
- t2 = edges[i].idx2;
- td = edges[i].weight;
- if(!cluster.is_connected(t1, t2)) // dokolku dvete teminja ne se vo isto drvo
- {
- izlez += td; // zgolemi go vkupniot zbir na rebrata na MST za tezinata na novoto rebro
- nov[i]=true;
- n_found++; // sum nashol novo teme
- cluster.merge_trees(t1, t2); // spoi gi
- }
- }
- //memset(nov1,false,sizeof(nov1));
- for(int i = 0; i < m; i++)
- {
- if(!nov[i])
- {
- continue;
- }
- nov1[i]=true;
- zbir=0;
- UF cluster1(n);
- n_found=0;
- for(int j = 0; j < m; j++)
- {
- t1 = edges[j].idx1;
- t2 = edges[j].idx2;
- td = edges[j].weight;
- if(nov1[j]==true)
- continue;
- if(!cluster1.is_connected(t1, t2)) // dokolku dvete teminja ne se vo isto drvo
- {
- zbir += td; // zgolemi go vkupniot zbir na rebrata na MST za tezinata na novoto rebro
- n_found++; // sum nashol novo teme
- cluster1.merge_trees(t1, t2); // spoi gi
- }
- }
- nov1[i]=false;
- if(n_found==n-1)
- MIN=min(MIN,zbir);
- }
- cout << izlez <<" "<<MIN<<endl;
- return(0);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement