Advertisement
Guest User

Untitled

a guest
Jun 22nd, 2017
47
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.39 KB | None | 0 0
  1. #include <vector>
  2. #include <string>
  3. #include <cstring>
  4. #include <queue>
  5. #include <iostream>
  6. #include <fstream>
  7. #include <algorithm>
  8. #include <cmath>
  9.  
  10. using namespace std;
  11.  
  12. int nextInt() {
  13.     int x;
  14.     scanf("%d", &x);
  15.     return x;
  16. }
  17.  
  18. char inp[10000];
  19. string nextString() {
  20.     scanf("%s", inp);
  21.     return inp;
  22. }
  23.  
  24. double nextDouble() {
  25.     double x;
  26.     scanf("%lf", &x);
  27.     return x;
  28. }
  29.  
  30. struct Edge {
  31.     int from;
  32.     int to;
  33.     int cost;
  34.     bool inSpaningTree;
  35. } edges[81000];
  36. int edgesCount = 0;
  37.  
  38. void addEdge(vector<vector<int> > &adj, int x, int y, int cost) {
  39.     edges[edgesCount].from = x;
  40.     edges[edgesCount].to = y;
  41.     edges[edgesCount].cost = cost;
  42.     adj[x].push_back(edgesCount++);
  43.  
  44.     edges[edgesCount].from = y;
  45.     edges[edgesCount].to = x;
  46.     edges[edgesCount].cost = cost;
  47.     adj[y].push_back(edgesCount++);
  48. }
  49.  
  50. bool edgeLess(int i, int j) {
  51.     Edge &a = edges[i];
  52.     Edge &b = edges[j];
  53.     return a.cost < b.cost;
  54. }
  55.  
  56. int parent[41000];
  57.  
  58. int Find(int x) {
  59.     if (parent[x] == x) {
  60.         return x;
  61.     }
  62.     return parent[x] = Find(parent[x]);
  63. }
  64.  
  65. bool Union(int x, int y) {
  66.     x = Find(x);
  67.     y = Find(y);
  68.     if (x == y) {
  69.         return false;
  70.     }
  71.     if (rand() % 2) {
  72.         swap(x, y);
  73.     }
  74.     parent[x] = y;
  75.     return true;
  76. }
  77.  
  78. void AddEdgeToTree(vector<vector<int> > &tree, int id) {
  79.     tree[edges[id].from].push_back(id);
  80.     edges[id].inSpaningTree = true;
  81. }
  82.  
  83. int used[41000];
  84.  
  85. void Erase(vector<int> &a, int x) {
  86.     edges[x].inSpaningTree = false;
  87.     a.erase(find(a.begin(), a.end(), x));
  88. }
  89.  
  90. void dfsMark(int v, vector<vector<int> > &tree, int usedVal) {
  91.     used[v] = usedVal;
  92.     for (int i = 0; i < tree[v].size(); ++i) {
  93.         int u = edges[tree[v][i]].to;
  94.         if (used[u] != usedVal) {
  95.             dfsMark(u, tree, usedVal);
  96.         }
  97.     }
  98. }
  99.  
  100. int bestCost, bestId;
  101.  
  102. void dfsFindEdge(int v, vector<vector<int> > &tree, vector<vector<int> > &adj, int usedVal) {
  103.     used[v] = -usedVal;
  104.     for (int i = 0; i < adj[v].size(); ++i) {
  105.         int id = adj[v][i];
  106.         Edge &e = edges[id];
  107.         if (e.cost < bestCost) {
  108.             bestCost = e.cost;
  109.             bestId = id;
  110.         }
  111.     }
  112.     for (int i = 0; i < tree[v].size(); ++i) {
  113.         int u = edges[tree[v][i]].to;
  114.         if (used[u] == usedVal) {
  115.             dfsMark(u, tree, usedVal);
  116.         }
  117.     }
  118. }
  119.  
  120. void dfsBiggestEdge(int v, int to, vector<vector<int> > &tree, int usedVal, int curMax, int curId) {
  121.     if (v == to) {
  122.         if (curMax > bestCost) {
  123.             bestCost = curMax;
  124.             bestId = curId;
  125.         }
  126.         return;
  127.     }
  128.     used[v] = usedVal;
  129.     for (int i = 0; i < tree[v].size(); ++i) {
  130.         int id = tree[v][i];
  131.         int u = edges[id].to;
  132.         if (used[u] != usedVal) {
  133.             int newMax = curMax;
  134.             int newId = curId;
  135.             if (edges[id].cost > newMax) {
  136.                 newMax = edges[id].cost;
  137.                 newId = id;
  138.             }
  139.             dfsBiggestEdge(u, to, tree, usedVal, newMax, newId);
  140.         }
  141.     }
  142. }
  143.  
  144. int main() {
  145.     int n = nextInt();
  146.     int m = nextInt();
  147.  
  148.     vector<vector<int> > adj(n);
  149.     vector<vector<int> > tree(n);
  150.  
  151.     for (int i = 0; i < m; ++i) {
  152.         int x = nextInt() - 1;
  153.         int y = nextInt() - 1;
  154.         int cost = nextInt();
  155.         addEdge(adj, x, y, cost);
  156.     }
  157.  
  158.     for (int i = 0; i < n; ++i) {
  159.         parent[i] = i;
  160.     }
  161.     vector<int> order(m * 2);
  162.     for (int i = 0; i < order.size(); ++i) {
  163.         order[i] = i;
  164.     }
  165.     sort(order.begin(), order.end(), edgeLess);
  166.     int totalCost = 0;
  167.     for (int t = 0; t < order.size(); ++t) {
  168.         int i = order[t];
  169.         int x = edges[i].from;
  170.         int y = edges[i].to;
  171.         if (Union(x, y)) {
  172.             AddEdgeToTree(tree, i);
  173.             AddEdgeToTree(tree, i ^ 1);
  174.             totalCost += edges[i].cost;
  175.         }
  176.     }
  177.  
  178.     memset(used, -1, sizeof(used));
  179.     int q = nextInt();
  180.     while (q--) {
  181.         int id = 2 * (nextInt() - 1);
  182.         int newCost = nextInt();
  183.         if (rand() % 2) {
  184.             id ^= 1;
  185.         }
  186.         int x = edges[id].from;
  187.         int y = edges[id].to;
  188.  
  189.         if (edges[id].inSpaningTree) {
  190.             totalCost -= edges[id].cost;
  191.             Erase(tree[x], id);
  192.             Erase(tree[y], id ^ 1);
  193.             edges[id].cost = newCost;
  194.  
  195.             dfsMark(y, tree, q + 1);
  196.             bestCost = 1000000;
  197.             dfsFindEdge(y, tree, adj, q + 1);
  198.            
  199.             AddEdgeToTree(tree, bestId);
  200.             AddEdgeToTree(tree, bestId ^ 1);
  201.             totalCost += edges[bestId].cost;
  202.         } else {
  203.             edges[id].cost = newCost;
  204.             bestCost = -1;
  205.             dfsBiggestEdge(x, y, tree, q + 1, -1, -1);
  206.             if (bestCost > newCost) {
  207.                 totalCost -= bestCost;
  208.                 Erase(tree[edges[bestId].from], bestId);
  209.                 Erase(tree[edges[bestId ^ 1].from], bestId ^ 1);
  210.  
  211.                 AddEdgeToTree(tree, id);
  212.                 AddEdgeToTree(tree, id ^ 1);
  213.                 totalCost += edges[id].cost;
  214.             }
  215.         }
  216.  
  217.         printf("%d\n", totalCost);
  218.     }
  219.  
  220.     return 0;
  221. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement