Advertisement
Romanchenko

problem356

Nov 3rd, 2017
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.67 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. struct Edge
  6. {
  7.     int u, v;
  8.     int w;
  9.     int id;
  10.     bool operator <(Edge x)
  11.     {
  12.         return w < x.w || (w == x.w && id < x.id);
  13.     }
  14. };
  15.  
  16. bool cmp(Edge a, Edge b)
  17. {
  18.     return a.id < b.id;
  19. }
  20.  
  21. vector<Edge> g;
  22.  
  23. vector<int> p;
  24.  
  25. int get(int v)
  26. {
  27.     if (v == p[v])
  28.         return v;
  29.     return p[v] = get(p[v]);
  30. }
  31.  
  32. void unite(int a, int b)
  33. {
  34.     a = get(a);
  35.     b = get(b);
  36.     if (a == b)
  37.         return;
  38.     if (rand() % 2)
  39.         p[a] = b;
  40.     else
  41.         p[b] = a;  
  42. }
  43.  
  44.  
  45. const int INF = -1e9;
  46. int uu = 0;
  47.  
  48. int dfs(int v, int s, int ep, vector< set<int> > &g1, vector<int> &used, vector<int> &path)
  49. {
  50.     used[v] = uu;
  51.     for (auto ei : g1[v])
  52.     {
  53.        
  54.         Edge e = g[ei];
  55.         int to = e.v;
  56.         if (to == v)
  57.             to = e.u;
  58.         if (to == s && ei != ep)
  59.         {
  60.             path.push_back(ei);
  61.             return 1;
  62.         }
  63.         if (used[to] != uu)
  64.         {
  65.             int r = dfs(to, s, ei, g1, used, path);
  66.             if (r)
  67.             {
  68.                 path.push_back(ei);
  69.                 return 1;
  70.             }
  71.         }
  72.     }
  73.     return 0;
  74. }
  75.  
  76. int main()
  77. {
  78.     ios_base::sync_with_stdio(false);
  79.     cin.tie(0);
  80.     //freopen("input.txt", "r", stdin);
  81.     int n, m;
  82.     cin >> n >> m;
  83.     p.resize(n);
  84.     for (int i = 0; i < n; i++)
  85.         p[i] = i;
  86.    
  87.     g.resize(m);
  88.     for (int i = 0; i < m; i++)
  89.     {
  90.         cin >> g[i].v >> g[i].u >> g[i].w;
  91.         g[i].v--;
  92.         g[i].u--;
  93.         g[i].id = i;
  94.     }
  95.     sort(g.begin(), g.end());
  96.     vector<int> used(m, 0);
  97.     vector<set<int> > g1(n);
  98.     set<int> mst;
  99.     for (int i = 0; i < m; i++)
  100.     {
  101.         int v = g[i].v;
  102.         int u = g[i].u;
  103.         int v1 = get(v);
  104.         int u1 = get(u);
  105.         if (u1 == v1)
  106.             continue;
  107.         unite(u1, v1);
  108.         used[i] = 1;
  109.         mst.insert(i);
  110.         g1[u].insert(i);
  111.         g1[v].insert(i);
  112.     }
  113.     vector<int> used1(n, 0);
  114.     int q = -1; // delete it
  115.     int p = -1; // add it
  116.     vector<int> path;
  117.     for (int i = 0; i < m; i++)
  118.     {
  119.         if (!used[i])
  120.         {
  121.             int u = g[i].u;
  122.             int v = g[i].v;
  123.             g1[v].insert(i);
  124.             g1[u].insert(i);
  125.             uu++;
  126.             path.clear();
  127.             int d = dfs(u, u, -1, g1, used1, path);
  128.             if (d)
  129.             {
  130.                 int tmp = -1;
  131.                 for (auto e : path)
  132.                 {
  133.                     if (e != i && (tmp == -1 || g[e].w > g[tmp].w))
  134.                         tmp = e;                   
  135.                 }
  136.                 if (p == -1 || q == -1 || (tmp != -1 && g[i].w - g[tmp].w < g[p].w - g[q].w))
  137.                 {
  138.                     p = i;
  139.                     q = tmp;
  140.                 }                  
  141.             }
  142.             g1[v].erase(i);
  143.             g1[u].erase(i);
  144.            
  145.         }
  146.     }
  147.     if (q == -1)
  148.     {
  149.         cout << -1;
  150.         return 0;
  151.     }
  152.     mst.erase(q);
  153.     mst.insert(p);
  154.     long long wei = 0;
  155.     vector<Edge> res;
  156.     for (auto x : mst)
  157.     {
  158.         res.push_back(g[x]);
  159.         wei += (long long)g[x].w;
  160.     }
  161.     sort(res.begin(), res.end(), cmp);
  162.     if ((int)res.size() != n - 1)
  163.     {
  164.         cout << -1;
  165.         return 0;
  166.     }
  167.    
  168.     cout << wei << endl;
  169.    
  170.     for (auto x : res)
  171.         cout << x.v + 1 << " " << x.u + 1 << " " << x.w << endl;
  172.     return 0;
  173. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement