[UR # 5] What more effort

Problem

Description

Popeye Jackson asked: "Master, a lot of things need to use a lot of energy to complete, while I was eating a lot of effort after the spinach, so he led me now rely heavily Spinach I hate my current situation, there is no way less. eat spinach even eat spinach still very effort? "

Jackson Smile, A:. "The method is very simple, but if you want me to teach you, you need to hand down the road."

Yamashita is \ (n-\) villages from \ (1 \) to the \ (n-\) ID, not connected between the path. Jackson gave Popeye a sketch, this sketch where (n \) \ villages are \ (n - 1 \) two-way road links to any of the villages can be reached by all the other villages in two-way road.

Now Popeye to build roads between the villages according to Jackson meaning. Popeye Jackson prescribed need to \ (m \) days to complete the task, in which Popeye the road as follows:

The first \ (I \) days, Jackson specify two villages \ (V_I \) and \ (u_i \) , on the sketch \ (V_I \) No. villages to \ (u_i \) all the numbers on the shortest path village villages (including \ (v_i \) and \ (u_i \) ), the need to elect a number of Popeye village (a village election can be repeated many times, of course, Popeye on this day can not choose one pair of villages) and the construction of a two-way road between the villages of each selected.
Popeye was found on a field trip, there \ (p \) limitation Relations \ ((t_i, a_i, b_i) \) , represents the first \ (t_i \) days can not \ (a_i \) village number to \ ( b_i \) inter-village road number (road is two-way, so naturally can not in \ (b_i \) to the village of numbers \ (a_i \) inter-village road number).
Each day has a value of effort required to repair \ (w_i \) , represents the first \ (i \) every day to build a road has to spend \ (w_i \) point strength values.
Popeye began to dry up brute force, a jar and a can of spinach to swallow, often the result of the construction of some useless roads are worn out every day.

As a spectator, you help Popeye determined to get \ (m \) days after any can reach each other, the total value of the effort required minimum number is between a pair of the village. Note that the last out of the road repair and sketch need not consistent.

Input Format

The first line of three non-negative integer \ (n-, m, P \) . Ensure \ (the n-\ geq 1 \) .

The next line \ (n - 1 \) integer, wherein the first \ (I \) integer \ (F_ {I}. 1 + \) ( \ (. 1 \ I +. 1 Leq F_ {} \ Leq I \) ) It represents a sketch \ (i + 1 \) No. villages and \ (f_ {i + 1} \) has a two-way path between the number of villages.

Next \ (m \) -th row, the \ (I \) line contains three integers \ (V_I, u_i, W_i \) ( \ (. 1 \ Leq V_I, u_i \ n-Leq, V_I \ NEQ u_i,. 1 \ Leq w_i \ Leq 10 ^ 9 \) ) represents the \ (i \) day Jackson specify \ (v_i \) number of villages and \ (u_i \) village number, Popeye repair a road takes \ (w_i \) point of strength values .

Next \ (p \) lines, each line containing three integers \ (t_i, a_i, b_i \ ) represents a restriction relationship. Ensure \ (. 1 \ Leq t_i \ Leq m \) , \ (. 1 \ Leq a_i, B_i \ Leq n-\) , \ (a_i \ NEQ B_i \) , and the sketch \ (a_i \) No. villages and \ (B_i \) No. villages in \ (v_ {t_i} \) No. villages to \ (u_ {t_i} \) on the shortest path number villages. Further, to ensure that no duplication of the input limit relationship, i.e., no two restricted relation \ (i, j \) satisfies \ (t_i = t_j, a_i = a_j, b_i = b_j \) or \ (t_i = t_j , a_i = b_j, b_i = a_j \) .

Output Format

A line output integer represents the minimum value of the total effort required. To ensure the presence of at least one of the road between the pair of any such method can reach each village.

Please when C / C ++ input and output Long Long %lld. C ++ can be used directly cin / cout input and output.

Sample

Input

5 2 3
1 1 3 3
2 4 1
5 4 2
1 3 2
1 3 1
1 3 4

Output

6

Explanation

Explanation for Input

Popeye first day could have been \ () \ (1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4) between the road , but not on the first day because \ ((3, 2), (3, 1) \) and \ ((3, 4) \) between the road, it is possible to select only \ ((1, 2), (1, 4), (2, 4) \) . For the second day, Popeye Possible choices are \ ((3, 4), (3, 5), (4, 5) \) .

One possible solution is optimal, in the first day of Popeye ((1, 2), (1, 4) \) \ road between the next day in \ ((3, 4), (4, 5 ) \) between the road, a total cost \ (1 + 1 + 2 + 2 = 6 \) point strength values.

Range

For \ (10 \% \) , \ (n-\ Leq 100, m \ Leq 100, P \ Leq 100 \)

For \ (30 \% \) , \ (n-\ 300000 Leq, m \ Leq 300000, P = 0 \)

For \ (20 is \% \) , \ (n-\ Leq 300000, m \ Leq 300000, P \ Leq 300000 \) , to ensure that for \ (. 1 <I \ Leq n-\) , \ (F_ {I +. 1} = i \)

For \ (40 \% \) , \ (n-\ Leq 300000 \) \ (m \ Leq 300000 \) \ (P \ Leq 300000 \)

Postscript

Thanks to your help, Popeye successful completion of the road and the strength value used is the original plan \ (0.01 \% \) .

Popeye Jackson said: "I understand I had previously been using brute force, from now on I want to Duo Sisuo, and more clever use force to solve the problem!."

Jackson waved his hand, hehe smile: "I'm sorry, I just want you to help build roads it."

Popeye eating a can of spinach, the Jackson killed.

Algorithm

Disjoint-set

Mentality

Is not difficult to imagine, the process should be like \ (kruskal \) as first day in accordance with the \ (w_i \) is sorted, then in the case of satisfying the requirements of the day, as much as possible the merged Unicom block them.

The next question is how specific merged.

There is a very obvious optimization, can reduce the complexity of this question a lot: For the first \ (i \) days, let \ (p_i \) to limit the number of the day. If \ (DIS (u_i, v_i)> P_i \) , so \ ((u, v) \ ) can be communication between all points on this path.

So in this case, maintaining disjoint-set, where each jump in the chain set and check the roots, then he and his father to the merger. Also note that the roots should be disjoint-set minimum depth point within the block Unicom. Overall complexity \ (O (n-) \) .

Moreover, the disjoint-set should be maintained separately from this case and another case of, or an error.

As for the other case, because \ (DIS (u_i, v_i) <P_i \) , we direct each point on the path are taken on the trip, anyway, the total number does not exceed \ (the p-\) .

For each day, all limit \ ((a, b) \ ) , the \ ((a, b) \ ) between an upper limit side is connected. We find the smallest degree of restricted edge of the point \ (x \) , consider first \ (x \) on the path of all the \ (x \) between no limit to the edge points are merged together.

One obvious conclusion: The minimum degree of degree up to the point \ (\ sqrt {m} \ ) level ( \ (m \) is the number of edges).

And so the \ (X \) set of points connected configuration of edges (we call \ (S \) ), we can directly \ (| S | ^ 2 \ ) determines whether to merge between any two limit edges. Then consider each (S \) \ point in determining whether it is capable of (S \) \ point outside combined arbitrarily. Because of those points will be the \ (x \) merger, so directly to the point \ (x \) be merged. This is only part of the complexity of the \ (O (the p-) \) .

Code

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
using namespace std;
long long read() {
  long long x = 0, w = 1;
  char ch = getchar();
  while (!isdigit(ch)) w = ch == '-' ? -1 : 1, ch = getchar();
  while (isdigit(ch)) {
    x = (x << 3) + (x << 1) + ch - '0';
    ch = getchar();
  }
  return x * w;
}
const int Max_n = 3e5 + 5;
int n, m, p, nd;
int fa[Max_n], f[Max_n], fl[Max_n], dep[Max_n], jp[20][Max_n];
int cntr, hd[Max_n], nx[Max_n << 1], to[Max_n];
int top, t, stk[Max_n], b2[Max_n], s[Max_n], S[Max_n], du[Max_n];
bool bk[Max_n], rd[600][600];
long long ans;
vector<int> ul[Max_n], vl[Max_n];
struct day {
  int u, v, w, id;
} k[Max_n];
void addr(int u, int v) {
  cntr++;
  nx[cntr] = hd[u], to[cntr] = v;
  hd[u] = cntr;
}
bool cmp(day a, day b) { return a.w < b.w; }
void build(int x) {
  jp[0][x] = fa[x], f[x] = fl[x] = x, dep[x] = dep[fa[x]] + 1;
  for (int i = hd[x]; i; i = nx[i]) build(to[i]);
}
int find(int *f, int x) { return f[x] == x ? x : f[x] = find(f, f[x]); }
int get_lca(int u, int v) {
  if (dep[u] < dep[v]) swap(u, v);
  for (int i = 19; ~i; i--)
    if (dep[jp[i][u]] >= dep[v]) u = jp[i][u];
  for (int i = 19; ~i; i--)
    if (jp[i][u] != jp[i][v]) u = jp[i][u], v = jp[i][v];
  return u == v ? u : jp[0][u];
}
void merge(int u, int v) {
  u = find(f, u), v = find(f, v);
  if (u == v) return;
  ans += k[nd].w;
  f[u] = v;
}
int main() {
#ifndef ONLINE_JUDGE
  freopen("61.in", "r", stdin);
  freopen("61.out", "w", stdout);
#endif
  n = read(), m = read(), p = read();
  for (int i = 2; i <= n; i++) addr(fa[i] = read(), i);
  for (int i = 1; i <= m; i++)
    k[i].u = read(), k[i].v = read(), k[i].w = read(), k[i].id = i;
  sort(k + 1, k + m + 1, cmp);
  while (p--) {
    int d = read();
    ul[d].push_back(read());
    vl[d].push_back(read());
  }
  du[0] = 1e9, build(1);
  for (int j = 1; j <= 19; j++)
    for (int i = 1; i <= n; i++) jp[j][i] = jp[j - 1][jp[j - 1][i]];
  for (nd = 1; nd <= m; nd++) {
    int x = k[nd].id, U = k[nd].u, V = k[nd].v;
    int lca = get_lca(U, V);
    if (dep[U] + dep[V] - 2 * dep[lca] > ul[x].size()) {
      for (int i = find(fl, U); dep[i] > dep[lca]; i = fa[i])
        fl[i] = fa[i], merge(fa[i], i);
      for (int i = find(fl, V); dep[i] > dep[lca]; i = find(fl, fa[i]))
        fl[i] = fa[i], merge(fa[i], i);
    } else {
      stk[top = 1] = lca, bk[lca] = 1;
      for (int i = U; i != lca; i = fa[i]) stk[++top] = i, bk[i] = 1;
      for (int i = V; i != lca; i = fa[i]) stk[++top] = i, bk[i] = 1;
      for (int i = ul[x].size() - 1; ~i; i--) {
        int u = ul[x][i], v = vl[x][i];
        if (bk[u] && bk[v]) du[u]++, du[v]++;
      }
      int Min = 0;
      for (int i = 1; i <= top; i++)
        if (du[Min] > du[stk[i]]) Min = stk[i];
      for (int i = ul[x].size() - 1; ~i; i--) {
        int u = ul[x][i], v = vl[x][i];
        if (bk[u] && bk[v]) du[u]--, du[v]--;
        if (u == Min) b2[v] = ++t, s[t] = v;
        if (v == Min) b2[u] = ++t, s[t] = u;
      }
      for (int i = 1; i <= top; i++)
        if (!b2[stk[i]]) merge(Min, stk[i]);
      for (int i = ul[x].size() - 1; ~i; i--) {
        int u = ul[x][i], v = vl[x][i];
        if (b2[u] && b2[v]) rd[b2[u]][b2[v]] = rd[b2[v]][b2[u]] = 1;
        if (b2[u] && !b2[v]) S[u]++;
        if (b2[v] && !b2[u]) S[v]++;
      }
      for (int i = 1; i < t; i++)
        for (int j = i + 1; j <= t; j++)
          if (!rd[i][j]) merge(s[i], s[j]);
      for (int i = 1; i <= t; i++)
        if (S[s[i]] < top - t) merge(s[i], Min);
      for (int i = ul[x].size() - 1; ~i; i--) {
        int u = ul[x][i], v = vl[x][i];
        if (b2[u] && b2[v]) rd[b2[u]][b2[v]] = rd[b2[v]][b2[u]] = 0;
        if (b2[u] && !b2[v]) S[u]--;
        if (b2[v] && !b2[u]) S[v]--;
      }
      while (t) b2[s[t--]] = 0;
      while (top) bk[stk[top--]] = 0;
    }
  }
  cout << ans << endl;
}

Guess you like

Origin www.cnblogs.com/luoshuitianyi/p/11442399.html