题意:

给出一颗边带权的数,树上的点有黑色和白色。求一条长度最大且黑色节点不超过k个的最长路径,输出最长的长度。

分析:

说一下题目的坑点:

  • 定义递归函数的前面要加inline,否则会RE。不知道这是什么鬼,=_=|。
  • ans要初始化为0,而不是一个绝对值很大的负数,因为我们可以选择只有一个顶点的路径,这样权值就是0。

题解请戳这还有这

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
#define MP make_pair
using namespace std; typedef pair<int, int> PII; const int maxn = 200000 + 10;
const int INF = 0x3f3f3f3f; struct Edge
{
int v, w, nxt;
Edge() {}
Edge(int v, int w, int nxt): v(v), w(w), nxt(nxt) {}
}; int n, k, m, ans;
int black[maxn];
vector<int> a; int ecnt, head[maxn];
Edge edges[maxn * 2]; inline void AddEdge(int u, int v, int w) {
edges[ecnt] = Edge(v, w, head[u]);
head[u] = ecnt++;
} int fa[maxn], sz[maxn];
int dep[maxn], f[maxn], g[maxn], num[maxn];
bool del[maxn]; inline void dfs(int u) {
sz[u] = 1;
for(int i = head[u]; ~i; i = edges[i].nxt) {
int v = edges[i].v;
if(del[v] || v == fa[u]) continue;
fa[v] = u;
dfs(v);
sz[u] += sz[v];
}
} inline PII findCenter(int u, int t) {
PII ans(INF, u);
int m = 0;
for(int i = head[u]; ~i; i = edges[i].nxt) {
int v = edges[i].v;
if(del[v] || v == fa[u]) continue;
m = max(m, sz[v]);
ans = min(ans, findCenter(v, t));
}
m = max(m, t - sz[u]);
return min(ans, MP(m, u));
} inline void getdep(int u, int p) {
dep[u] = 0;
for(int i = head[u]; ~i; i = edges[i].nxt) {
int v = edges[i].v;
if(v == p || del[v]) continue;
getdep(v, u);
dep[u] = max(dep[u], dep[v]);
}
dep[u] += black[u];
} bool cmp(int a, int b) { return dep[edges[a].v] < dep[edges[b].v]; } inline void getg(int u, int p, int d, int c) {
g[c] = max(g[c], d);
for(int i = head[u]; ~i; i = edges[i].nxt) {
Edge& e = edges[i];
if(e.v == p || del[e.v]) continue;
getg(e.v, u, d + e.w, c + black[e.v]);
}
} inline void solve(int u) {
fa[u] = 0;
dfs(u);
int s = findCenter(u, sz[u]).second;
del[s] = true; for(int i = head[s]; ~i; i = edges[i].nxt) {
int v = edges[i].v;
if(del[v]) continue;
solve(v);
} int tot = 0;
for(int i = head[s]; ~i; i = edges[i].nxt) {
int v = edges[i].v;
if(del[v]) continue;
getdep(v, s);
num[++tot] = i;
} sort(num + 1, num + 1 + tot, cmp); int mxdep = dep[edges[num[tot]].v];
for(int i = 0; i <= mxdep; i++) f[i] = -INF;
for(int i = 1; i <= tot; i++) {
int v = edges[num[i]].v, w = edges[num[i]].w;
int d = dep[v];
for(int j = 0; j <= d; j++) g[j] = -INF;
getg(v, s, w, black[v]); if(i != 1) {
for(int j = 0; j <= k - black[s] && j <= d; j++) {
int j2 = min(dep[edges[num[i-1]].v], k - black[s] - j);
if(f[j2] == -INF) break;
if(g[j] != -INF) ans = max(ans, g[j] + f[j2]);
}
} for(int j = 0; j <= d; j++) {
f[j] = max(f[j], g[j]);
if(j) f[j] = max(f[j], f[j-1]);
if(j + black[s] <= k) ans = max(ans, f[j]);
}
} del[s] = false;
} int main()
{
scanf("%d%d%d", &n, &k, &m);
while(m--) {
int x; scanf("%d", &x);
black[x] = 1;
} ecnt = 0;
memset(head, -1, sizeof(head));
for(int i = 1; i < n; i++) {
int u, v, w; scanf("%d%d%d", &u, &v, &w);
AddEdge(u, v, w);
AddEdge(v, u, w);
} ans = 0;
solve(1);
printf("%d\n", ans); return 0;
}

SPOJ 1825 Free tour II 树分治的更多相关文章

  1. [spoj] FTOUR2 FREE TOUR II || 树分治

    原题 给出一颗有n个点的树,其中有M个点是拥挤的,请选出一条最多包含k个拥挤的点的路径使得经过的权值和最大. 正常树分治,每次处理路径,更新答案. 计算每棵子树的deep(本题以经过拥挤节点个数作为d ...

  2. SPOJ 1825 Free tour II (树的点分治)

    题目链接 Free tour II 题意:有$N$个顶点的树,节点间有权值, 节点分为黑点和白点. 找一条最长路径使得 路径上黑点数量不超过K个 这是树的点分治比较基本的题,涉及树上启发式合并……仰望 ...

  3. spoj 1825 Free tour II

    http://www.spoj.com/problems/FTOUR2/ After the success of 2nd anniversary (take a look at problem FT ...

  4. SPOJ:Free tour II (树分治+启发式合并)

    After the success of 2nd anniversary (take a look at problem FTOUR for more details), this 3rd year, ...

  5. 【SPOJ】1825. Free tour II(点分治)

    http://www.spoj.com/problems/FTOUR2/ 先前看了一会题解就自己yy出来了...对拍过后交tle.................. 自己造了下大数据........t ...

  6. SPOJ 1825 Free Tour | 终极之树分治

    求树上最长路径使得经过的拥挤节点个数不超过K //欢迎访问这个博客!http://www.cnblogs.com/luyouqi233/p/8036828.html #include<cstdi ...

  7. SPOJ FTOUR2 - Free tour II

    Description 有些黑点,问你选择不超过 \(k\) 个黑点的路径,路径权值最大是多少. Sol 点分治. 这是qzc的论文题,不过我感觉他的翻译好强啊...我还是选择了自己去看题目... 点 ...

  8. SP1825 FTOUR2 - Free tour II 点分治+启发式合并+未调完

    题意翻译 给定一棵n个点的树,树上有m个黑点,求出一条路径,使得这条路径经过的黑点数小于等于k,且路径长度最大 Code: #include <bits/stdc++.h> using n ...

  9. SPOJ1825 FTOUR2 - Free tour II

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

随机推荐

  1. D. Statistics of Recompressing Videos

    D. Statistics of Recompressing Videos time limit per test 3 seconds memory limit per test 256 megaby ...

  2. 编译安装php容易出现的问题以及解决办法

    http://crybit.com/20-common-php-compilation-errors-and-fix-unix/

  3. 第一天课程-html基础

    一.课程内容: 1.安装需要的软件 安装了三个软件:Adobe Dreamweaver,EmEditor,FSCapture.分别是前端开发软件.功能强大的文本编辑器,截图录屏软件 2.了解文件格式. ...

  4. 关于Kettle的事务和转换内步骤的顺序执行

    关于Kettle的事务和转换内步骤的顺序执行 近来有项目中遇到Kettle事务处理和转换内步骤顺序执行的问题.为此进行了研究,找到了一个解决办法. 在Kettle中,一个Job内的转换,缺省是顺序执行 ...

  5. 3D图形引擎决定三维产业差异化

    从2009年中国3D产业初步兴起开始,短短几年间中国的3D技术得到了飞速的发展,3D打印机.3D投影仪.Web3D.虚拟现实.场景漫游等等产业应用应运而生,设备制造商和内容提供商都开始发挥自主创新的优 ...

  6. android dialog style属性设置

    <!--最近做项目,用到alertDialog,用系统自带的style很难看,所以查了资料自己定义了个style. res/value/style.xml内增加以下代码:--> <s ...

  7. 洛谷 P2014 选课

    题目描述 在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程来学习,在课程里有些课程必须在某些课程之前学习,如高等数学总是在其它课程之前学习.现在有N门功课,每门课有个学分,每门课有一 ...

  8. 随记:UWP开发中怎么使当前页面拓展到标题栏

    public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); CoreAp ...

  9. Logback文档(1)

    http://b6ec263c.wiz03.com/share/s/2SX2oY0nX4f32CY5ax1bapaL030VCK2svQZU2rRyDR05KMh5

  10. codeforce Gym 100500F Door Lock (二分)

    根据题意略推一下,其实就是问你满足(a*(a+1))/2 < m <= ((a+1)*a(a+2))/2的a和m-(a*(a+1))/2 -1是多少. 二分求解就行了 #include&l ...