题意:给一棵树,求树上长度小于等于k的链的数量。

题解:http://blog.csdn.net/yang_7_46/article/details/9966455 照着这个博客写的代码。

不到100行,所以不应该算难吧……可是我觉得好难啊……

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
int n, k;
const int N = ;
struct Edge {
int to, cost;
};
vector<Edge> g[N];
vector<int> dep; // 记录一个子树所有节点到根的距离
int sz[N]; // 记录每个子树的大小 最大子树最小的是重心
bool used[N]; // 记录每个节点是否被计算过
int minsz, root; // 重心的最大子树大小 重心
int size;
int ans;
void up(int &x, int y) { if(y>x) x=y; }
int Scan() {
int x = ; char C = getchar();
while (C < '' || C > '') C = getchar();
while (C >= '' && C <= '') { x = x * - '' + C, C = getchar(); }
return x;
}
void getroot(int u, int fa) { //找到重心
sz[u] = ;
int maxn = ;
for (unsigned i = ; i < g[u].size(); ++i) {
int v = g[u][i].to;
if (v == fa || used[v]) continue; // 因为每次都是找重心 递归求解 求过的不需要再求了
getroot(v, u);
sz[u] += sz[v];
up(maxn, sz[v]);
}
up(maxn, size-sz[u]); // size不是n 因为每次寻找的树只是一个子树
if (maxn < minsz) minsz = maxn, root = u;
}
void getdep(int u, int fa, int dis) { // 寻找子树内每一个结点到根的长度
dep.push_back(dis);
sz[u] = ;
for (unsigned i = ; i < g[u].size(); ++i) {
int v = g[u][i].to;
if (v == fa || used[v]) continue;
getdep(v, u, dis+g[u][i].cost);
sz[u] += sz[v];
}
} int cal(int u, int dis) { // dep求得u的所有子树长度,返回的是经过根节点的答案
dep.clear();
getdep(u, , dis);
sort(dep.begin(), dep.end());
int l = , r = dep.size()-;
int res = ;
while (l<r) {
if (dep[l]+dep[r] <= k) res += r-l++;
else r--;
}
return res;
} void solve(int u) { // 对于每一个结点求解 答案是经过这个结点和不经过这个结点的和
ans += cal(u, );
used[u] = true;
for (unsigned i = ; i < g[u].size(); ++i) {
int v = g[u][i].to;
if (used[v]) continue;
ans -= cal(v, g[u][i].cost); // 如果两个点位于同一棵子树会重复计算 减去
minsz = n, root = , size = sz[v]; // size的大小应该是这个子树的大小
getroot(v, );
solve(root);
}
} int main() {
while (~scanf("%d%d", &n, &k)) {
if (n == && k == ) break;
int u, v, c;
for (int i = ; i <= n; ++i) g[i].clear();
memset(used, , sizeof used);
for (int i = ; i < n; ++i) {
u = Scan(), v = Scan(), c = Scan();
g[u].push_back(Edge{v, c});
g[v].push_back(Edge{u, c});
}
minsz = n, root = , size = n;
getroot(, );
ans = ;
solve(root);
printf("%d\n", ans);
}
return ;
}

poj1741-Tree(树的分治)的更多相关文章

  1. [poj1741][tree] (树/点分治)

    Description Give a tree with n vertices,each edge has a length(positive integer less than 1001). Def ...

  2. POJ1741——Tree(树的点分治)

    1 /* *********************************************** 2 Author :kuangbin 3 Created Time :2013-11-17 1 ...

  3. POJ 1741 Tree 树的分治

    原题链接:http://poj.org/problem?id=1741 题意: 给你棵树,询问有多少点对,使得这条路径上的权值和小于K 题解: 就..大约就是树的分治 代码: #include< ...

  4. POJ1741 Tree 树分治模板

    http://poj.org/problem?id=1741   题意:一棵n个点的树,每条边有距离v,求该树中距离小于等于k的点的对数.   dis[y]表示点y到根x的距离,v代表根到子树根的距离 ...

  5. poj 1741 Tree (树的分治)

    Tree Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 30928   Accepted: 10351 Descriptio ...

  6. POJ1741 tree 【点分治】

    Tree Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 25286   Accepted: 8421 Description ...

  7. POJ 1741 Tree 树的分治(点分治)

    题目大意:给出一颗无根树和每条边的权值,求出树上两个点之间距离<=k的点的对数. 思路:树的点分治.利用递归和求树的重心来解决这类问题.由于满足题意的点对一共仅仅有两种: 1.在以该节点的子树中 ...

  8. [poj1741 Tree]树上点分治

    题意:给一个N个节点的带权树,求长度小于等于K的路径条数 思路:选取一个点作为根root,假设f(root)是当前树的答案,那么答案来源于两部分: (1)路径不经过root,那么就是完全在子树内,这部 ...

  9. E. Alternating Tree 树点分治|树形DP

    题意:给你一颗树,然后这颗树有n*n条路径,a->b和b->a算是一条,然后路径的权值是 vi*(-1)^(i+1)  注意是点有权值. 从上头往下考虑是点分治,从下向上考虑就是树形DP, ...

  10. POJ1741 tree (点分治模板)

    题目大意: 给一棵有 n 个顶点的树,每条边都有一个长度(小于 1001 的正整数).定义 dist(u,v)=节点 u 和 v 之间的最小距离.给定一个整数 k,对于每一对 (u,v) 顶点当且仅当 ...

随机推荐

  1. ecos内核概览--bakayi译

    http://blog.csdn.net/wangzaiwei2006/article/details/6453423

  2. VC中支持中文的字符串比较函数

    VS2008开发环境,多字符集和UNICODE字符集都可用. WCHAR * mbcsToUnicode(const char *zStr) { int nByte; WCHAR *zMbcsStr; ...

  3. Android:属性scaleType与图片的显示

    ImageView是Android中的基础图片显示控件,该控件有个重要的属性是ScaleType,该属性用以表示显示图片的方式, 共有8种取值 matrix 用矩阵来绘制(从左上角起始的矩阵区域) f ...

  4. node.js模块之fs文件系统

    fs 模块是文件操作的封装,它提供了文件的读取.写入.更名.删除.遍历目录.链接等 POSIX 文件系统操作.与其他模块不同的是,fs 模块中所有的操作都提供了异步的和同步的两个版本, 例如读取文件内 ...

  5. 【转】奇异值分解(We Recommend a Singular Value Decomposition)

    文章转自:奇异值分解(We Recommend a Singular Value Decomposition) 文章写的浅显易懂,很有意思.但是没找到转载方式,所以复制了过来.一个是备忘,一个是分享给 ...

  6. Complete The Pattern #2

    Complete The Pattern #2 Description: Task: You have to write a function pattern which creates the fo ...

  7. Android学习Service中遇到的问题

    今天学习service,然后遇到了一个force close,log中存在这个一句话: 05-23 14:13:26.408: E/AndroidRuntime(17616): android.con ...

  8. 1220. Stacks

    1220 又一神题啊  卡内存可以卡到这种地步 省得不行了 开两个[N]数组 一个来记录前驱  一个存数 记录前驱的用unsigned short类型 最大可达65535 不过可以标记一下是否比这个数 ...

  9. poj 1259 Agri-Net(最小生成树)

    题目:http://poj.org/problem?id=1258 题意:模板题 和2485差不多 就是求相连后的最小值. #include <iostream> #include< ...

  10. Python中,如何初始化不同的变量类型为空值

    参考文章  Python中,如何初始化不同的变量类型为空值 常见的数字,字符,很简单,不多解释. 列表List的其值是[x,y,z]的形式 字典Dictionary的值是{x:a, y:b, z:c} ...