#include <cstdio> #include <bitset> #include <vector> const int N = 20005; int n, ord[N], cmp[N], sz[N], cind, ans[N]; std::vector<std::pair<int, long long> > g[N]; long long r[N]; bool u[N], edg[N][N], edg1[N][N]; std::bitset<N> reach[N], cedg[N]; void calc(int start, int v, long long d = 0, int pr = -1) { if (d > r[start]) return; edg[start][v] = 1; edg1[v][start] = 1; for (int i = 0; i < (int)g[v].size(); ++i) if (g[v][i].first != pr) calc(start, g[v][i].first, d + g[v][i].second, v); } void dfs1(int v) { static int dt = 0; u[v] = 1; for (int i = 0; i < n; ++i) if (!u[i] && edg[v][i]) dfs1(i); ord[dt++] = v; } void dfs2(int v) { cmp[v] = cind; ++sz[cind]; for (int i = 0; i < n; ++i) if (edg1[v][i]) { if (!cmp[i]) dfs2(i); cedg[cmp[i]][cind] = 1; } } int main() { scanf("%d", &n); for (int i = 0; i < n; ++i) scanf("%lld", r + i); for (int i = 1; i < n; ++i) { int a, b; long long c; scanf("%d%d%lld", &a, &b, &c); --a; --b; g[a].push_back(std::make_pair(b, c)); g[b].push_back(std::make_pair(a, c)); } for (int i = 0; i < n; ++i) calc(i, i); for (int i = 0; i < n; ++i) if (!u[i]) dfs1(i); for (int i = n - 1; i >= 0; --i) if (!cmp[ord[i]]) { ++cind; dfs2(ord[i]); } for (int i = cind; i >= 1; --i) { reach[i][i] = 1; for (int j = i + 1; j <= cind; ++j) if (cedg[i][j] && !reach[i][j]) reach[i] |= reach[j]; for (int j = i; j <= cind; ++j) if (reach[i][j]) ans[i] += sz[j]; } for (int i = 0; i < n; ++i) printf("%d ", ans[cmp[i]]); printf("\n"); return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | #include <cstdio> #include <bitset> #include <vector> const int N = 20005; int n, ord[N], cmp[N], sz[N], cind, ans[N]; std::vector<std::pair<int, long long> > g[N]; long long r[N]; bool u[N], edg[N][N], edg1[N][N]; std::bitset<N> reach[N], cedg[N]; void calc(int start, int v, long long d = 0, int pr = -1) { if (d > r[start]) return; edg[start][v] = 1; edg1[v][start] = 1; for (int i = 0; i < (int)g[v].size(); ++i) if (g[v][i].first != pr) calc(start, g[v][i].first, d + g[v][i].second, v); } void dfs1(int v) { static int dt = 0; u[v] = 1; for (int i = 0; i < n; ++i) if (!u[i] && edg[v][i]) dfs1(i); ord[dt++] = v; } void dfs2(int v) { cmp[v] = cind; ++sz[cind]; for (int i = 0; i < n; ++i) if (edg1[v][i]) { if (!cmp[i]) dfs2(i); cedg[cmp[i]][cind] = 1; } } int main() { scanf("%d", &n); for (int i = 0; i < n; ++i) scanf("%lld", r + i); for (int i = 1; i < n; ++i) { int a, b; long long c; scanf("%d%d%lld", &a, &b, &c); --a; --b; g[a].push_back(std::make_pair(b, c)); g[b].push_back(std::make_pair(a, c)); } for (int i = 0; i < n; ++i) calc(i, i); for (int i = 0; i < n; ++i) if (!u[i]) dfs1(i); for (int i = n - 1; i >= 0; --i) if (!cmp[ord[i]]) { ++cind; dfs2(ord[i]); } for (int i = cind; i >= 1; --i) { reach[i][i] = 1; for (int j = i + 1; j <= cind; ++j) if (cedg[i][j] && !reach[i][j]) reach[i] |= reach[j]; for (int j = i; j <= cind; ++j) if (reach[i][j]) ans[i] += sz[j]; } for (int i = 0; i < n; ++i) printf("%d ", ans[cmp[i]]); printf("\n"); return 0; } |