mr_dot_convict

KOICOST-SPOJ-mr.convict

May 15th, 2019
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.74 KB | None | 0 0
  1. /*author* Priyanshu Shrivastav (from IIT Palakkad) *
  2.  * *_ __ ___  _ ______ ___  _ ____   ___  ___| |_  *
  3.  * | '_ ` _ \| '__/ __/ _ \| '_ \ \ / / |/ __| __| *
  4.  * | | | | | | | | (_| (_) | | | \ V /| | (__| |_  *
  5.  * |_| |_| |_|_|(_)___\___/|_| |_|\_/ |_|\___|\__| *
  6. When I wrote this, only God and I understood what I was doing
  7.  ** * * * * * * * Now, only God knows * * * * * * */
  8. #include         <bits/stdc++.h>
  9. #pragma GCC      optimize ("Ofast")
  10. #pragma GCC      optimize ("unroll-loops")
  11. #pragma GCC      target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
  12.  
  13. #define IOS      ios_base::sync_with_stdio(false); cin.tie (nullptr)
  14. #define PREC     cout.precision (10); cout << fixed
  15. #define x        first
  16. #define y        second
  17. using namespace std;
  18. using ll = long long;
  19.  
  20. const int N = (int)1e6 + 10;
  21. const int M = (int)1e6 + 10;
  22. const int infi = (int)1e9;
  23.  
  24. struct Edge {
  25.    int u, v;
  26.    ll w;
  27.    inline bool operator > (const Edge &o) const {
  28.       return w > o.w;
  29.    }
  30. };
  31.  
  32. int n, m;
  33. int rep[N], rnk[N], sz[N];
  34. vector <Edge> edges;
  35. ll cum[M];
  36.  
  37. template <typename T> T add(const T& a, const T& b) {
  38.    return (a + b) % infi;
  39. }
  40. template <typename T> T mul(const T& a, const T& b) {
  41.    return (a * b) % infi;
  42. }
  43.  
  44. void makeSet() {
  45.    for(int i = 0; i < n; ++i)
  46.       rep[i] = i, rnk[i] = 0, sz[i] =  1;
  47. }
  48.  
  49. int findSet(int u) {
  50.    int ru = u;
  51.    while (ru != rep[ru])
  52.       ru = rep[ru];
  53.  
  54.    while (u != rep[u]) {
  55.       int tmp = rep[u];
  56.       rep[u] = ru;
  57.       u = tmp;
  58.    }
  59.    return ru;
  60. }
  61.  
  62. void mergeSet(int u, int v) {
  63.    int ru = findSet(u), rv = findSet(v);
  64.    if (rnk[ru] > rnk[rv]) {
  65.       rep[rv] = rep[ru];
  66.       sz[ru] += sz[rv];
  67.    }
  68.    else {
  69.       rep[ru] = rep[rv];
  70.       sz[rv] += sz[ru];
  71.    }
  72.  
  73.    if (rnk[ru] == rnk[rv]) {
  74.       ++rnk[rv];
  75.    }
  76. }
  77.  
  78. void solve() {
  79.    ll ans = 0;
  80.    sort (edges.begin(), edges.end(), greater <Edge>());
  81.  
  82.    for (int i = m - 1; i >= 0; --i) {
  83.       if (i == m - 1) cum[i] = edges[i].w;
  84.       else cum[i] = add <ll> (cum[i + 1], edges[i].w);
  85.    }
  86.  
  87.    makeSet();
  88.  
  89.    for (int i = 0; i < m; ++i) {
  90.       Edge e = edges[i];
  91.       int u = e.u, v = e.v;
  92.       int ru = findSet(u), rv = findSet(v);
  93.       if (ru == rv) continue;
  94.  
  95.       ans = add <ll> (ans, mul<ll>((1ll* sz[ru] * sz[rv]), cum[i]));
  96.       mergeSet(u, v);
  97.    }
  98.    cout << ans << '\n';
  99. }
  100.  
  101. void read() {
  102.    edges.clear();
  103.    for (int i = 0; i < m; ++i) cum[i] = 0;
  104.    int u, v, w;
  105.    for (int i = 0; i < m; ++i) {
  106.       cin >> u >> v >> w;
  107.       --u, --v;
  108.       if (u > v) swap(u, v);
  109.       edges.push_back({u, v, 1ll*w});
  110.    }
  111.    assert ((int)edges.size() == m);
  112. }
  113.  
  114. signed main() {
  115.    while (cin >> n >> m) {
  116.       read(); solve();
  117.    }
  118.  
  119.    return EXIT_SUCCESS;
  120. }
Add Comment
Please, Sign In to add comment