题意:给一棵树,求树上长度小于等于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. 用QT创建新风格: QStyle

    转贴: http://hi.baidu.com/yjj2008/blog/item/6cd4a1892ef0d4b60f2444a5.html 本文介绍了如何使用qt提供的接口来设计自己的GUI风格( ...

  2. font-size:100%和font-size:0

    h1,h2,h3,h4,h5,h6 {font-size:100%;} 正常情况下hx按照一定百分比增加字号,但是指定font-size:100%;就会继承body设置的字体大小 font-size: ...

  3. 几种必知的oracle结构图

    一.数据库结构 二.Oracle 内存结构 三.进程结构 1. 用户进程:在数据库用户请求连接到Oracle 服务器时启动 2. 服务器进程:可以连接到Oracle实例,它在用户建立会话时启动 3. ...

  4. 【原创】ZYNQ学习笔记(一) HelloWorld实现

    拿过ZYNQ开发板,里面给了很多部件,果断从网上下载了手册,N多手册和原理图. 要比Spartan-6复杂多了,耐心地看了看,知道ZYNQ系列分为PS(系统)以及PL(逻辑)部分. 之前,自己一直在做 ...

  5. xcopy 复制了0个文件

    xcopy /Y "..\..\..\SolutionItems\zbmyuncore.db" "..\ZITaker" 复制zbmyuncore.db文件的时 ...

  6. Android开发UI之给ImageView添加蒙版

    ImageView控件添加蒙版, 通过属性:android:tint="" 比如 android:tint="#44ff0000"

  7. Android开发之json解析

    目前正在尝试着写app,发现看懂代码和能写出来差距很大,最关键的是java基础比较的差,因为只会python,java基础只学习了一个礼拜就过了.感觉java写出来的代码不如python简单明了. 上 ...

  8. JPA详解

    2006 年 5 月 2 日,EJB 3.0 规范最终版由 JCP(Java Community Process) 正式公布,标准号为 JSR(Java Specification Request)2 ...

  9. naotu.baidu.com 非常棒的脑图在线工具

    1.png 2.txt 短租 前台功能 房源查看 房源搜索 城市房源 注册登录 预定房源 房源退订 在线支付 评价房源 个人中心 我的订单 我的账户 我的收藏 消息通知 管理员后台 房源发布 会员管理 ...

  10. HDU 1503 Advanced Fruits (LCS,变形)

    题意: 给两个水果名,要求他们的LCS部分只输出1次,其他照常输出,但是必须保持原来的顺序! 思路: 求LCS是常规的,但是输出麻烦了,要先求LCS,再标记两串中的所有LCS字符,在遇到LCS字符时, ...