Advertisement
Guest User

Untitled

a guest
Oct 16th, 2019
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.09 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <stack>
  4. #include <map>
  5. #include <algorithm>
  6.  
  7. using namespace std;
  8.  
  9. struct edge {
  10.     int from;
  11.     int to;
  12.     int weight;
  13. };
  14.  
  15. vector<vector<pair<int, int>>> graph;
  16.  
  17. int cnt_vertex, cnt_edges;
  18.  
  19. void topSort(int v, vector<bool> &used, map<int, vector<int>> &zeroEdges, vector<int> &ord) {
  20.     used[v] = true;
  21.     if (zeroEdges.find(v) != zeroEdges.end()) {
  22.         for (auto u : zeroEdges[v]) {
  23.             if (!used[u]) {
  24.                 topSort(u, used, zeroEdges, ord);
  25.             }
  26.         }
  27.     }
  28.     ord.push_back(v);
  29. }
  30.  
  31. void dfsReverse(int v, vector<int> &component, int cnt_comp, map<int, vector<int>> &zeroEdgesReverse) {
  32.     component[v] = cnt_comp;
  33.     if (zeroEdgesReverse.find(v) != zeroEdgesReverse.end()) {
  34.         for (auto u : zeroEdgesReverse[v]) {
  35.             if (component[u] == -1) {
  36.                 dfsReverse(u, component, cnt_comp, zeroEdgesReverse);
  37.             }
  38.         }
  39.     }
  40. }
  41.  
  42. int condensation(vector<int> &component, map<int, vector<int>> &zeroEdges,
  43.                  map<int, vector<int>> &zeroEdgesReverse, int cnt_v) {
  44.     vector<bool> used;
  45.     vector<int> ord;
  46.     component.resize(cnt_v, -1);
  47.     used.resize(cnt_v, false);
  48.     for (int i = 0; i < cnt_v; i++) {
  49.         if (!used[i]) {
  50.             topSort(i, used, zeroEdges, ord);
  51.         }
  52.     }  
  53.     reverse(ord.begin(), ord.end());
  54.     int cnt_comp = 0;
  55.     for (auto v : ord) {
  56.         if (component[v] == -1) {
  57.             dfsReverse(v, component, cnt_comp, zeroEdgesReverse);
  58.             cnt_comp++;
  59.         }
  60.     }
  61.     return cnt_comp;
  62. }
  63.  
  64. void dfsConnect(int v, vector<bool> &used, map<int, vector<int>> &zeroEdges) {
  65.     used[v] = true;
  66.     if (zeroEdges.find(v) != zeroEdges.end()) {
  67.         for (auto u : zeroEdges[v]) {
  68.             if (!used[u]) {
  69.                 dfsConnect(u, used, zeroEdges);
  70.             }
  71.         }
  72.     }
  73. }
  74.  
  75. long long findMST(const vector<edge> &edges, int n, int root) {
  76.     long long res = 0;
  77.     int minEdge[n];
  78.     for (int i = 0; i < n; i++) {
  79.         minEdge[i] = INT32_MAX;
  80.     }
  81.     for (auto e : edges) {
  82.         minEdge[e.to] = min(e.weight, minEdge[e.to]);
  83.     }
  84.     for (int i = 0; i < n; i++) {
  85.         if (i == root) {
  86.             continue;
  87.         }
  88.         res += minEdge[i];
  89.     }
  90.     map<int, vector<int>> zeroEdges{};
  91.     map<int, vector<int>> zeroEdgesReverse{};
  92.     for (auto e :edges) {
  93.         if (e.weight == minEdge[e.to]) {
  94.             zeroEdges[e.from].push_back(e.to);
  95.             zeroEdgesReverse[e.to].push_back(e.from);
  96.         }
  97.     }
  98.     vector<bool> used;
  99.     used.resize(n, false);
  100.     dfsConnect(root, used, zeroEdges);
  101.     bool isConnected = true;
  102.     for (int i = 0; i < n; i++) {
  103.         if (!used[i]) {
  104.             isConnected = false;
  105.             break;
  106.         }
  107.     }
  108.     if (isConnected) {
  109.         return res;
  110.     }
  111.     vector<int> newComponents;
  112.     vector<edge> newEdges;
  113.     int cnt_comp = condensation(newComponents, zeroEdges, zeroEdgesReverse, n);
  114.     for (auto e : edges) {
  115.         if (newComponents[e.to] != newComponents[e.from]) {
  116.             newEdges.push_back({newComponents[e.from], newComponents[e.to], e.weight - minEdge[e.to]});
  117.         }
  118.     }
  119.  
  120.     res += findMST(newEdges, cnt_comp, newComponents[root]);
  121.     return res;
  122. }
  123.  
  124. void dfsMain(int v, vector<bool> &used) {
  125.     used[v] = true;
  126.     for (auto u : graph[v]) {
  127.         if (!used[u.first]) {
  128.             dfsMain(u.first, used);
  129.         }
  130.     }
  131. }
  132.  
  133. int main() {
  134.     cin >> cnt_vertex >> cnt_edges;
  135.     vector<edge> edges;
  136.     graph.resize(cnt_vertex);
  137.     for (int i = 0; i < cnt_edges; i++) {
  138.         int from, to, weight;
  139.         cin >> from >> to >> weight;
  140.         graph[from - 1].push_back(make_pair(to - 1, weight));
  141.         edges.push_back({from - 1, to - 1, weight});
  142.     }
  143.     vector<bool> used;
  144.     used.resize(cnt_vertex, false);
  145.     dfsMain(0, used);
  146.     for (int i = 0; i < cnt_vertex; i++) {
  147.         if (!used[i]) {
  148.             cout << "NO\n";
  149.             return 0;
  150.         }
  151.     }
  152.     cout << "YES\n" << findMST(edges, cnt_vertex, 0);
  153.  
  154. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement