poj1741-Tree(树的分治)
题意:给一棵树,求树上长度小于等于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(树的分治)的更多相关文章
- [poj1741][tree] (树/点分治)
Description Give a tree with n vertices,each edge has a length(positive integer less than 1001). Def ...
- POJ1741——Tree(树的点分治)
1 /* *********************************************** 2 Author :kuangbin 3 Created Time :2013-11-17 1 ...
- POJ 1741 Tree 树的分治
原题链接:http://poj.org/problem?id=1741 题意: 给你棵树,询问有多少点对,使得这条路径上的权值和小于K 题解: 就..大约就是树的分治 代码: #include< ...
- POJ1741 Tree 树分治模板
http://poj.org/problem?id=1741 题意:一棵n个点的树,每条边有距离v,求该树中距离小于等于k的点的对数. dis[y]表示点y到根x的距离,v代表根到子树根的距离 ...
- poj 1741 Tree (树的分治)
Tree Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 30928 Accepted: 10351 Descriptio ...
- POJ1741 tree 【点分治】
Tree Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 25286 Accepted: 8421 Description ...
- POJ 1741 Tree 树的分治(点分治)
题目大意:给出一颗无根树和每条边的权值,求出树上两个点之间距离<=k的点的对数. 思路:树的点分治.利用递归和求树的重心来解决这类问题.由于满足题意的点对一共仅仅有两种: 1.在以该节点的子树中 ...
- [poj1741 Tree]树上点分治
题意:给一个N个节点的带权树,求长度小于等于K的路径条数 思路:选取一个点作为根root,假设f(root)是当前树的答案,那么答案来源于两部分: (1)路径不经过root,那么就是完全在子树内,这部 ...
- E. Alternating Tree 树点分治|树形DP
题意:给你一颗树,然后这颗树有n*n条路径,a->b和b->a算是一条,然后路径的权值是 vi*(-1)^(i+1) 注意是点有权值. 从上头往下考虑是点分治,从下向上考虑就是树形DP, ...
- POJ1741 tree (点分治模板)
题目大意: 给一棵有 n 个顶点的树,每条边都有一个长度(小于 1001 的正整数).定义 dist(u,v)=节点 u 和 v 之间的最小距离.给定一个整数 k,对于每一对 (u,v) 顶点当且仅当 ...
随机推荐
- 用QT创建新风格: QStyle
转贴: http://hi.baidu.com/yjj2008/blog/item/6cd4a1892ef0d4b60f2444a5.html 本文介绍了如何使用qt提供的接口来设计自己的GUI风格( ...
- font-size:100%和font-size:0
h1,h2,h3,h4,h5,h6 {font-size:100%;} 正常情况下hx按照一定百分比增加字号,但是指定font-size:100%;就会继承body设置的字体大小 font-size: ...
- 几种必知的oracle结构图
一.数据库结构 二.Oracle 内存结构 三.进程结构 1. 用户进程:在数据库用户请求连接到Oracle 服务器时启动 2. 服务器进程:可以连接到Oracle实例,它在用户建立会话时启动 3. ...
- 【原创】ZYNQ学习笔记(一) HelloWorld实现
拿过ZYNQ开发板,里面给了很多部件,果断从网上下载了手册,N多手册和原理图. 要比Spartan-6复杂多了,耐心地看了看,知道ZYNQ系列分为PS(系统)以及PL(逻辑)部分. 之前,自己一直在做 ...
- xcopy 复制了0个文件
xcopy /Y "..\..\..\SolutionItems\zbmyuncore.db" "..\ZITaker" 复制zbmyuncore.db文件的时 ...
- Android开发UI之给ImageView添加蒙版
ImageView控件添加蒙版, 通过属性:android:tint="" 比如 android:tint="#44ff0000"
- Android开发之json解析
目前正在尝试着写app,发现看懂代码和能写出来差距很大,最关键的是java基础比较的差,因为只会python,java基础只学习了一个礼拜就过了.感觉java写出来的代码不如python简单明了. 上 ...
- JPA详解
2006 年 5 月 2 日,EJB 3.0 规范最终版由 JCP(Java Community Process) 正式公布,标准号为 JSR(Java Specification Request)2 ...
- naotu.baidu.com 非常棒的脑图在线工具
1.png 2.txt 短租 前台功能 房源查看 房源搜索 城市房源 注册登录 预定房源 房源退订 在线支付 评价房源 个人中心 我的订单 我的账户 我的收藏 消息通知 管理员后台 房源发布 会员管理 ...
- HDU 1503 Advanced Fruits (LCS,变形)
题意: 给两个水果名,要求他们的LCS部分只输出1次,其他照常输出,但是必须保持原来的顺序! 思路: 求LCS是常规的,但是输出麻烦了,要先求LCS,再标记两串中的所有LCS字符,在遇到LCS字符时, ...