营销型网站建设的意义,网上哪些网站可以做设计项目,网站建设报价,2017 上海网站备案Acwing 252. 树
题意#xff1a;
给定一个有 N 个点#xff08;编号 0,1,…,N−1#xff09;的树#xff0c;每条边都有一个权值#xff08;不超过 1000#xff09;。
树上两个节点 x 与 y 之间的路径长度就是路径上各条边的权值之和。
求长度不超过 K 的路径有多少条…Acwing 252. 树
题意
给定一个有 N 个点编号 0,1,…,N−1的树每条边都有一个权值不超过 1000。
树上两个节点 x 与 y 之间的路径长度就是路径上各条边的权值之和。
求长度不超过 K 的路径有多少条。 1≤N≤104, 1≤K≤5×106, 0≤l≤103
题解
P4178 Tree,和这个题题意是一样的但是本题的数据范围更大本题k5e6,且空间只给了10MB树状数组的方法是不行需要用容斥 我们cal直接记录以u为出发点的所有路径长度用数组d来存对数组d排序然后利用尺取的方法来确定有多少对长度之和小于k。但是这样是会造成重复的 对于图中绿色两点其路径应该是紫色线但是我们在计算u时会将红色部分也计算进去因此我们要将多余部分删去对于u的儿子节点v我们计算一遍以v为出发点的路径(还要额外加上边长dis(u,v) )有多少对长度之和小于k,相当于绿线部分然后减去绿线部分相当于将多余部分删去
代码
#include bits/stdc.h
#include unordered_map
#define debug(a, b) printf(%s %d\n, a, b);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pairint, int PII;
clock_t startTime, endTime;
//Fe~Jozky
const ll INF_ll 1e18;
const int INF_int 0x3f3f3f3f;
void read(){};
template typename _Tp, typename... _Tps void read(_Tp x, _Tps... Ar)
{x 0;char c getchar();bool flag 0;while (c 0 || c 9)flag| (c -), c getchar();while (c 0 c 9)x (x 3) (x 1) (c ^ 48), c getchar();if (flag)x -x;read(Ar...);
}
template typename T inline void write(T x)
{if (x 0) {x ~(x - 1);putchar(-);}if (x 9)write(x / 10);putchar(x % 10 0);
}
void rd_test()
{
#ifdef LOCALstartTime clock();freopen(in.txt, r, stdin);
#endif
}
void Time_test()
{
#ifdef LOCALendTime clock();printf(\nRun Time:%lfs\n, (double)(endTime - startTime) / CLOCKS_PER_SEC);
#endif
}
const int maxn 1e5 9;
int n, k;
vectorPII vec[maxn];
int vis[maxn];
int rt, cnt;
int sz[maxn], d[maxn];
void dfs_rt(int u, int fa, int tot)
{sz[u] 1;int maxx 0;for (auto it : vec[u]) {int v it.first;int w it.second;if (v fa || vis[v])continue;dfs_rt(v, u, tot);sz[u] sz[v];maxx max(maxx, sz[v]);}maxx max(maxx, tot - sz[u]);if (2 * maxx tot)rt u;
}
void dfs_dis(int u, int fa, int dis)
{d[cnt] dis; //记录了所有路径长度for (auto it : vec[u]) {int v it.first;int w it.second;if (v fa || vis[v])continue;dfs_dis(v, u, dis w);}
}
int calc(int u, int w)
{cnt 0;dfs_dis(u, 0, w);sort(d 1, d 1 cnt);int l 1, r cnt, ans 0;while (l r) {while (d[l] d[r] k l r)r--;/*d是递增的当d[l]d[r]k时此后所有r到l这段都是小于k的*/ans (r - l);l;}return ans;
}
int solve(int u, int fa, int tot)
{dfs_rt(u, fa, tot);u rt;vis[u] 1;int res calc(u, 0);for (auto it : vec[u]) {int v it.first;int w it.second;if (vis[v])continue;res- calc(v, w);res solve(v, u, cnt);}return res;
}
int main()
{//rd_test();while (1) {read(n, k);if (!n !k)break;for (int i 1; i n; i)vec[i].clear();for (int i 1; i n; i)vis[i] 0;int u, v, w;for (int i 1; i n; i) {read(u, v, w);u;v;vec[u].push_back({v, w});vec[v].push_back({u, w});}printf(%d\n, solve(1, 0, n));}return 0;//Time_test();
}