Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cstdio>
- #include <memory.h>
- #include <algorithm>
- #include <vector>
- #include <cassert>
- using namespace std;
- const int N = 300500;
- const int inf = 1000 * 1000 * 1000 + 42;
- int R[N];
- vector<pair<int, int> > E[N];
- int cur_layer = 0;
- vector<pair<int, int> > L[2 * N];
- int lpt[2 * N];
- int S[N];
- bool dead[N];
- vector<pair<int, int> > ver_L[N];
- int DFS(int x, int sz, int p = -1)
- {
- S[x] = 1;
- int pass_root = -1;
- for (int i = 0; i < E[x].size(); i++)
- {
- int y = E[x][i].first;
- if (y == p)
- continue;
- if (dead[y])
- {
- swap(E[x][i], E[x].back());
- --i;
- E[x].pop_back();
- continue;
- }
- int r = DFS(y, sz, x);
- if (r != -1)
- pass_root = r;
- S[x] += S[y];
- }
- bool ok = (sz - S[x]) <= sz / 2;
- for (int i = 0; i < E[x].size(); i++)
- {
- int y = E[x][i].first;
- ok &= S[y] <= sz / 2;
- }
- if (ok)
- pass_root = x;
- return pass_root;
- }
- void DFS2(int x, int l = 0, int p = -1)
- {
- L[cur_layer].push_back(make_pair(l, x));
- if (R[x] >= l)
- ver_L[x].push_back(make_pair(cur_layer, R[x] - l));
- S[x] = 1;
- for (int i = 0; i < E[x].size(); i++)
- {
- int y = E[x][i].first;
- int d = E[x][i].second;
- if (y == p)
- continue;
- DFS2(y, min(l + d, inf), x);
- S[x] += S[y];
- }
- }
- void create_layer(int x, int sz)
- {
- L[cur_layer].reserve(sz);
- int root = DFS(x, sz);
- assert(root != -1);
- DFS2(root);
- sort(L[cur_layer].begin(), L[cur_layer].end());
- dead[root] = true;
- cur_layer++;
- for (int i = 0; i < E[root].size(); i++)
- create_layer(E[root][i].first, S[E[root][i].first]);
- }
- vector<int> ord;
- bool was[N];
- void mark(int x)
- {
- was[x] = true;
- for (int i = 0; i < ver_L[x].size(); i++)
- {
- int l = ver_L[x][i].first;
- int d = ver_L[x][i].second;
- while (lpt[l] != L[l].size() && L[l][lpt[l]].first <= d)
- {
- int y = L[l][lpt[l]++].second;
- if (!was[y])
- mark(y);
- }
- }
- ord.push_back(x);
- }
- int main()
- {
- #ifndef LOCAL42
- freopen("alarm.in", "r", stdin);
- freopen("alarm.out", "w", stdout);
- #endif
- int n;
- scanf("%d", &n);
- for (int i = 0; i < n; i++)
- scanf("%d", &R[i]);
- for (int i = 0; i < n - 1; i++)
- {
- int a, b, l;
- scanf("%d %d %d", &a, &b, &l);
- --a, --b;
- E[a].push_back(make_pair(b, l));
- E[b].push_back(make_pair(a, l));
- }
- create_layer(0, n);
- for (int i = 0; i < cur_layer; i++)
- sort(L[i].begin(), L[i].end());
- ord.reserve(n);
- for (int i = 0; i < n; i++)
- if (!was[i])
- mark(i);
- vector<int> rord;
- rord.swap(ord);
- ord.reserve(n);
- reverse(rord.begin(), rord.end());
- int ans = 0;
- memset(was, 0, sizeof(was));
- memset(lpt, 0, sizeof(lpt));
- for (int i = 0; i < rord.size(); i++)
- if (!was[rord[i]])
- mark(rord[i]), ans++;
- printf("%d\n", ans);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement