思路:
点分治入门题
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<algorithm> #include<cmath> #include<vector> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e4 + 5; int head[N], son[N], maxson[N], d[N], cnt = 0, ans = 0, rt, n, k; bool vis[N]; vector<int>deep; struct edge { int to, w, nxt; }edge[N*2]; void add_edge(int u, int v, int w) { edge[cnt].to = v; edge[cnt].w = w; edge[cnt].nxt = head[u]; head[u] = cnt++; } void get_rt(int o, int u) { son[u] = 1; maxson[u] = 0; for (int i = head[u]; ~i; i = edge[i].nxt) { if(edge[i].to != o && !vis[edge[i].to]) { get_rt(u, edge[i].to); son[u] += son[edge[i].to]; maxson[u] = max(maxson[u], son[edge[i].to]); } } maxson[u] = max(maxson[u], n - son[u]); if(maxson[u] < maxson[rt]) rt = u; } void get_d(int o, int u) { deep.pb(d[u]); son[u] = 1; for (int i = head[u]; ~i; i = edge[i].nxt) { if(edge[i].to != o && !vis[edge[i].to]) { d[edge[i].to] = d[u] + edge[i].w; get_d(u, edge[i].to); son[u] += son[edge[i].to]; } } } int cal(int u, int dis) { deep.clear(); d[u] = dis; get_d(0, u); sort(deep.begin(), deep.end()); int res = 0; for (int l = 0, r = deep.size()-1; l < r;) { if(deep[l] + deep[r] <= k) res += r - l++; else r--; } return res; } void work(int u) { ans += cal(u, 0); vis[u] = true; for (int i = head[u]; ~i; i = edge[i].nxt) { if(!vis[edge[i].to]) { ans -= cal(edge[i].to, edge[i].w); maxson[0] = n = son[edge[i].to]; get_rt(rt = 0, edge[i].to); work(rt); } } } int main() { int u, v, w; while(~scanf("%d%d", &n, &k) && n && k) { mem(head, -1); mem(vis, false); ans = cnt = 0; for (int i = 1; i < n; i++) { scanf("%d%d%d", &u, &v, &w); add_edge(u, v, w); add_edge(v, u, w); } maxson[0] = n; get_rt(rt = 0, 1); work(rt); printf("%d ", ans); } return 0; }
2019.3
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<cstdio> #include<iostream> #include<vector> #include<cstring> #include<algorithm> #include<cmath> using namespace std; #define y1 y11 #define fi first #define se second #define pi acos(-1.0) #define LL long long #define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pli pair<LL, int> #define pii pair<int, int> #define piii pair<pii, int> #define pdd pair<double, double> #define mem(a, b) memset(a, b, sizeof(a)) #define debug(x) cerr << #x << " = " << x << " "; #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); const int N = 1e4 + 5; const int INF = 0x3f3f3f3f; int son[N], n, k, u, v, w, ans = 0; vector<pii> g[N]; vector<int> deep; bool vis[N]; void get_sz(int u, int o) { son[u] = 1; for (int i = 0; i < g[u].size(); ++i) { int v = g[u][i].fi; if(!vis[v] && v != o) { get_sz(v, u); son[u] += son[v]; } } } pii get_center(int u, int o, int tot) { pii res = mp(INF, -1); int m = 0, tmp = 1; for (int i = 0; i < g[u].size(); ++i) { int v = g[u][i].fi; if(!vis[v] && v != o) { res = min(res, get_center(v, u, tot)); m = max(m, son[v]); tmp += son[v]; } } m = max(m, tot-tmp); res = min(res, mp(m, u)); return res; } void get_deep(int u, int o, int d) { deep.pb(d); for (int i = 0; i < g[u].size(); ++i) { int v = g[u][i].fi; int w = g[u][i].se; if(!vis[v] && v != o) { get_deep(v, u, d + w); } } } int cal() { int res = 0; sort(deep.begin(), deep.end()); for (int l = 0, r = deep.size()-1; l < r; ) { if(deep[l] + deep[r] <= k) res += r - l++; else r--; } deep.clear(); return res; } void solve(int u) { get_sz(u, u); pii p = get_center(u, u, son[u]); int c = p.se; vis[c] = true; get_deep(c, c, 0); ans += cal(); for (int i = 0; i < g[c].size(); ++i) { int v = g[c][i].fi; if(!vis[v]) solve(v); } for (int i = 0; i < g[c].size(); ++i) { int v = g[c][i].fi; int w = g[c][i].se; if(!vis[v]) { get_deep(v, v, w); ans -= cal(); } } vis[c] = false; } int main() { while(~scanf("%d %d", &n, &k) && (n || k)) { for (int i = 1; i <= n; ++i) g[i].clear(), son[i] = 0; for (int i = 1; i < n; ++i) scanf("%d %d %d", &u, &v, &w), g[u].pb({v, w}), g[v].pb({u, w}); ans = 0; solve(1); printf("%d ", ans); } return 0; }