树的点分治 (poj 1741, 1655(树形dp))
poj 1655:http://poj.org/problem?id=1655
题意: 给无根树, 找出以一节点为根, 使节点最多的树,节点最少。
题解:一道树形dp,先dfs 标记 所有节点的子树的节点数。 再dfs 找出以某节点为根的最大子树,节点最少。 复杂度(n)
/***Good Luck***/
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <stack>
#include <map>
#include <queue>
#include <vector>
#include <set>
#include <functional>
#include <cmath> #define Zero(a) memset(a, 0, sizeof(a))
#define Neg(a) memset(a, -1, sizeof(a))
#define All(a) a.begin(), a.end()
#define PB push_back
#define inf 0x7fffffff
#define inf2 0x7fffffffffffffff
#define ll long long
using namespace std; const int maxn = ;
int n, k, e, head[maxn];
int mx[maxn], sum[maxn], ansn, ansb;
struct Node {
int next, v;
}node[maxn]; void input(int u, int v) {
node[e].next = head[u];
node[e].v = v;
head[u] = e++;
} int dfssize(int b, int fa) {
sum[b] = ;
mx[b] = ;
int tmpmx;
for (int i = head[b]; ~i; i = node[i].next) {
int v = node[i].v;
if (fa != v) {
tmpmx = dfssize(v, b);
sum[b] +=tmpmx;
if (tmpmx > mx[b]) mx[b] = tmpmx;
}
}
return sum[b];
} void solve(int b, int fa) {
int tmpmx;
tmpmx = max(mx[b], n - sum[b]);
if (tmpmx <= ansb) {
if (tmpmx < ansb) {
ansn = b;
ansb = tmpmx;
} else if (b < ansn) {
ansn = b;
ansb = tmpmx;
}
}
for (int i = head[b]; ~i; i = node[i].next) {
int v = node[i].v;
if (fa != v) {
solve(v, b);
}
}
} int main() {
int u, v;
int T;
scanf("%d", &T);
while (T-- ) {
scanf("%d", &n);
e = ;
Neg(head);
for (int i = ; i < n - ; ++i) {
scanf("%d%d", &u, &v);
input(u, v);
input(v, u);
}
dfssize(, );
ansb = inf;
solve(, );
printf("%d %d\n", ansn, ansb);
}
return ;
}
poj 1741:http://poj.org/problem?id=1741
题意:给一值k,在带权无向图G中, 找出两节点相距不大于k的数。
qzc论文的第一题(膜拜q神 orz),根据论文写的 代码, 先写了一题树形dp(1655),再开始写这的,搞了一晚上具体的还是看论文吧。
找根(n), 计算(logn), 一共执行 logn次 总复杂度(n*logn*logn)
/***Good Luck***/
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <stack>
#include <map>
#include <queue>
#include <vector>
#include <set>
#include <functional>
#include <cmath> #define Zero(a) memset(a, 0, sizeof(a))
#define Neg(a) memset(a, -1, sizeof(a))
#define All(a) a.begin(), a.end()
#define PB push_back
#define inf 0x3f3f3f3f
#define inf2 0x7fffffffffffffff
#define ll long long
using namespace std;
const int maxn = ;
int head[maxn], n, k, e;
int ans, sum[maxn], mx[maxn];
bool vis[maxn];
int dis[maxn], a[maxn], an;
struct Node {
int w;
int v, next;
}edge[maxn]; void init() {
e = ;
ans = ;
Neg(head);
Zero(vis);
} void add(int u, int v, int w) { //邻接表储存
edge[e].v = v;
edge[e].w = w;
edge[e].next = head[u];
head[u] = e++;
} int dfssize(int u, int fa) { //标记子树的节点数
sum[u] = ;
mx[u] = ;
int tmpmx;
for (int i = head[u]; ~i; i = edge[i].next) {
int v = edge[i].v;
if (v != fa && !vis[v]) {
tmpmx = dfssize(v, u);
sum[u] += tmpmx;
if (tmpmx > mx[u]) mx[u] = tmpmx;
}
}
return sum[u];
} int ansn, mxshu;
void find_root(int u, int fa, int nn) { // 找出符合条件的根。
int tmpmx = max(mx[u], nn - sum[u]);
if (tmpmx < mxshu) {
ansn = u;
mxshu = tmpmx;
}
for (int i = head[u]; ~i; i = edge[i].next) {
int v = edge[i].v;
if (v != fa && !vis[v]) {
find_root(v, u, nn);
}
}
} void dfsdis(int u, int fa) {
a[an++] = dis[u];
for (int i = head[u]; ~i; i = edge[i].next) {
int v = edge[i].v;
if (fa != v && !vis[v]) {
dis[v] = dis[u] + edge[i].w;
dfsdis(v, u);
}
}
} int cal(int u, int fa, int beg) { // 这个方法太神奇了 复杂度只有 (logn)
an = ;
int ret = ;
dis[u] = beg;
dfsdis(u, fa);
sort(a, a + an);
int l = , r = an - ;
while (l < r) {
if (a[r] + a[l] <= k )
ret += r - l++;
else
r--;
}
return ret;
} void solve(int u) {
dfssize(u, );
mxshu = inf;
find_root(u, , sum[u]);
vis[ansn] = true;
ans += cal(ansn, , );
for (int i = head[ansn]; ~i; i = edge[i].next) {
int v = edge[i].v;
if (!vis[v]) {
ans -= cal(v, ansn, edge[i].w);
solve(v);
}
}
}
int main() {
//freopen("data.out", "w", stdout);
//freopen("data.in", "r", stdin);
int u, v, w;
while (scanf("%d%d", &n, &k), n&&k) {
init();
for (int i = ; i < n - ; ++i) {
scanf("%d%d%d", &u, &v, &w);
add(u, v, w);
add(v, u, w);
}
solve();
printf("%d\n", ans);
}
return ;
}
树的点分治 (poj 1741, 1655(树形dp))的更多相关文章
- POJ 1741 Tree 树形DP(分治)
链接:id=1741">http://poj.org/problem?id=1741 题意:给出一棵树,节点数为N(N<=10000),给出N-1条边的两点和权值,给出数值k,问 ...
- 点分治——POJ 1741
写的第一道点分治的题目,权当认识点分治了. 点分治,就是对每条过某个点的路径进行考虑,若路径不经过此点,则可以对其子树进行考虑. 具体可以看menci的blog:点分治 来看一道例题:POJ 1741 ...
- Apple Tree POJ - 2486 (树形dp)
题目链接: D - 树形dp POJ - 2486 题目大意:一颗树,n个点(1-n),n-1条边,每个点上有一个权值,求从1出发,走V步,最多能遍历到的权值 学习网址:https://blog.c ...
- POJ 3107.Godfather 树形dp
Godfather Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 7536 Accepted: 2659 Descrip ...
- [POJ 1155] TELE (树形dp)
题目链接:http://poj.org/problem?id=1155 题目大意:电视台要广播电视节目,要经过中转机构,到观众.从电视台到中转商到观众是一个树形结构,经过一条边需要支付成本.现在给你每 ...
- Anniversary party POJ - 2342 (树形DP)
题目链接: POJ - 2342 题目大意:给你n个人,然后每个人的重要性,以及两个人之间的附属关系,当上属选择的时候,他的下属不能选择,只要是两个人不互相冲突即可.然后问你以最高领导为起始点的关系 ...
- POJ Anniversary party 树形DP
/* 树形dp: 给一颗树,要求一组节点,节点之间没有父子关系,并且使得所有的节点的权值和最大 对于每一个节点,我们有两种状态 dp[i][0]表示不选择节点i,以节点i为根的子树所能形成的节点集所能 ...
- POJ 3342 (树形DP)
题意 :给出一些上下级关系,要求i和i的直接上级不能同时出现,现在选出一些人构成一个集合,问你这个集合里面的最大人数是都少,同时给出这个最大的人数的集合是否唯一. 思路:树形DP,dp[i][0],表 ...
- POJ 2342 (树形DP)
Anniversary party Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 3863 Accepted: 2172 ...
- 树分治 poj 1741
n k n个节点的一棵树 k是距离 求树上有几对点距离<=k; #include<stdio.h> #include<string.h> #include<algo ...
随机推荐
- jmeter基本组件介绍
常用术语统一:元件-jmeter工具菜单的一个子菜单(功能) 组件-一组元件的集合.如http请求与取样器的的关系 jmeter测试计划要素: (1)脚本中测试计划只能有一个: (2)测试计划中至 ...
- Android SDK安装与环境变量的配置(windows系统)
(一)下载Android SDK压缩包 解压后即可(全英文路径,以免后续出现乱码) (1)下载地址:http://tools.android-studio.org/index.php/sdk
- Intellij idea 一个窗口打开多模块并添加依赖
打开多模块 ctrl+alt+shift+s 或者file->project sturcture 选择modules 添加 选择要添加的模块 选择从现有模块添加,不要选择从现在代码创建模块 添加 ...
- 文本查重算法SimHash
1.介绍 爬虫采集了大量的文本数据,如何进行去重?可以使用文本计算MD5,然后与已经抓取下来的MD5集合进行比较,但这种做法有个问题,文本稍有不同MD5值都会大相径庭, 无法处理文本相似问题.另一种方 ...
- Apollo报错找不到apollo.meta的问题解决方案
问题描述 Apollo报错,找不到apoll.meta,但是明明配置了apollo-env.properties到apollo-client内了. apollo-env.properties pro. ...
- vue-cli添加bootstrap
如何引入bootstrap npm install --save-dev bootstrap 在main.js中引入 import 'bootstrap/dist/css/bootstrap.min. ...
- Caused by: org.springframework.context.annotation.ConflictingBeanDefinitionException 异常
Caused by: org.springframework.context.annotation.ConflictingBeanDefinitionException 报此异常是应为有相同的bean ...
- python购物车小案例
python购物车小案例# 案列描述:有一个小型水果店里面有水果(苹果:¥8/kg,香蕉:¥5/kg,芒果:¥15/kg,葡萄:¥12/kg),客户带了100元钱进店选购水果.# 1.客户输入相应序号 ...
- Python爬虫常用小技巧之设置代理IP
设置代理IP的原因 我们在使用Python爬虫爬取一个网站时,通常会频繁访问该网站.假如一个网站它会检测某一段时间某个IP的访问次数,如果访问次数过多,它会禁止你的访问.所以你可以设置一些代理服务器来 ...
- 一个开源组件 bug 引发的分析
这是一个悲伤的故事.某日清晨,距离版本转测还剩一天,切图仔的我正按照计划有条不紊的画页面.当我点击一个下拉弹框组件中分页组件页数过多而出现的向后 5 页省略号时,悲剧开始了,弹框被收回了.情景再现 问 ...