http://www.spoj.com/problems/FTOUR2/

After the success of 2nd anniversary (take a look at problem FTOUR for more details), this 3rd year, Travel Agent SPOJ goes on with another discount tour.

The tour will be held on ICPC island, a miraculous one on the Pacific Ocean. We list N places (indexed from 1 to N) where the visitors can have a trip. Each road connecting them has an interest value, and this value can be negative(if there is nothing interesting to view there). Simply, these N places along with the roads connecting them form atree structure. We will choose two places as the departure and destination of the tour.

Since September is the festival season of local inhabitants, some places are extremely crowded (we call themcrowded places). Therefore, the organizer of the excursion hopes the tour will visit at most K crowded places (too tiring to visit many of them) and of course, the total number of interesting value should be maximum.

Briefly, you are given a map of N places, an integer K, and M id numbers of crowded place. Please help us to find the optimal tour. Note that we can visit each place only once (or our customers easily feel bored), also the departure and destination places don't need to be different.

Input

There is exactly one case. First one line, containing 3 integers N K M, with 1 <= N <= 200000, 0 <= K <= M, 0 <= M <=N.

Next M lines, each line includes an id number of a crowded place.

The last (N - 1) lines describe (N - 1) two-way roads connected N places, form a b i, with a, b is the id of 2 places, and i is its interest value (-10000 <= i <= 10000).

Output

Only one number, the maximum total interest value we can obtain.

Example

Input:
8 2 3
3
5
7
1 3 1
2 3 10
3 4 -2
4 5 -1
5 7 6
5 6 5
4 8 3 Output:
12 题意:n个点的一棵树,有m个黑点,问最多经过k个黑点的最长路径
点分治+启发式合并
对于每一个次的根节点,枚举计算每个孩子的子树中最多有几个黑点
注意当黑点数>k时,及时return k
按黑点数从小到大排序,
对于每个子树
计算子树中经过i个黑点的最长路径dis[i]
同时维护一个数组f,表示前i-1个孩子的各自子树内,经过黑点数<=j的最长路径
枚举这个子树经过多少个黑点,更新答案
有可能最长路就是子树内一个点与根节点之间,所以在计算dis[i]时,也要更新答案 具体看漆子超神犇的论文 为什么时间复杂度是nlogn呐?
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 200002
using namespace std;
int n,k,m,root,ans,max_black,all;
bool crowd[N],vis[N];
int tot,front[N],nxt[N<<],to[N<<],val[N<<];
int siz[N],big[N];
int dis[N],f[N];
struct node
{
int black,id,d;
}e[N];
void read(int &x)
{
x=; int f=; char c=getchar();
while(!isdigit(c)) { if(c=='-') f=-; c=getchar(); }
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
x*=f;
}
void add(int u,int v,int w)
{
to[++tot]=v; nxt[tot]=front[u]; front[u]=tot; val[tot]=w;
to[++tot]=u; nxt[tot]=front[v]; front[v]=tot; val[tot]=w;
}
void getroot(int x,int fa)
{
siz[x]=; big[x]=;
for(int i=front[x];i;i=nxt[i])
{
if(vis[to[i]] || to[i]==fa) continue;
getroot(to[i],x);
siz[x]+=siz[to[i]];
big[x]=max(big[x],siz[to[i]]);
}
big[x]=max(big[x],all-siz[x]);
if(big[x]<big[root]) root=x;
}
int cal_black(int x,int fa,int sum)
{
if(sum==k) return k;
int res=sum;
for(int i=front[x];i;i=nxt[i])
{
if(vis[to[i]] || to[i]==fa) continue;
res=max(res,cal_black(to[i],x,sum+crowd[to[i]]));
}
return res;
}
bool cmp(node p,node q)
{
return p.black<q.black;
}
void cal_dis(int x,int fa,int sum,int d)
{
if(sum<=k)
{
ans=max(ans,d);
dis[sum]=max(dis[sum],d);
}
for(int i=front[x];i;i=nxt[i])
{
if(to[i]==fa || vis[to[i]]) continue;
cal_dis(to[i],x,sum+crowd[to[i]],d+val[i]);
}
}
void cal(int x)
{
tot=max_black=;
for(int i=front[x];i;i=nxt[i])
{
if(vis[to[i]]) continue;
e[++tot].id=to[i];
e[tot].black=cal_black(to[i],x,crowd[to[i]]);
e[tot].d=val[i];
max_black=max(max_black,e[tot].black);
}
sort(e+,e+tot+,cmp);
memset(f,-,sizeof(*f)*(max_black+));
for(int i=;i<=tot;i++)
{
memset(dis,-,sizeof(*dis)*(e[i].black+));
cal_dis(e[i].id,x,crowd[e[i].id],e[i].d);
for(int j=crowd[e[i].id];j<=min(k-crowd[x],e[i].black);j++)
ans=max(ans,f[min(k-j-crowd[x],e[i-].black)]+dis[j]);
f[]=max(f[],dis[]);
for(int j=;j<=e[i].black;j++)
f[j]=max(f[j],dis[j]),f[j]=max(f[j-],f[j]);
}
}
void work(int x)
{
cal(x);
vis[x]=true;
for(int i=front[x];i;i=nxt[i])
{
if(vis[to[i]]) continue;
all=siz[to[i]];
root=;
getroot(to[i],);
work(root);
}
}
int main()
{
read(n); read(k); read(m);
int x;
while(m--)
{
read(x);
crowd[x]=true;
}
int u,v,w;
for(int i=;i<n;i++)
{
read(u); read(v); read(w);
add(u,v,w);
}
big[root]=n;
root=;
all=n;
getroot(,);
work(root);
printf("%d",ans);
}

spoj 1825 Free tour II的更多相关文章

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

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

  2. SPOJ 1825 Free tour II 树分治

    题意: 给出一颗边带权的数,树上的点有黑色和白色.求一条长度最大且黑色节点不超过k个的最长路径,输出最长的长度. 分析: 说一下题目的坑点: 定义递归函数的前面要加inline,否则会RE.不知道这是 ...

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

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

  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 FTOUR2 - Free tour II

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

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

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

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

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

  8. SPOJ1825 FTOUR2 - Free tour II

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

  9. 后缀自动机(SAM):SPOJ Longest Common Substring II

    Longest Common Substring II Time Limit: 2000ms Memory Limit: 262144KB A string is finite sequence of ...

随机推荐

  1. Scrum立会报告+燃尽图(十一月二十六日总第三十四次):上传β阶段展示视频

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2413 项目地址:https://git.coding.net/zhang ...

  2. 第六周的PSP

    本周PSP: 本周进度条: 累积进度图:: 本周PSP饼状图:

  3. winfrom 界面编辑之疑难杂症

    设计器方便,但是也存在一些问题: 1.找不到控件,但确实存在——被隐藏或被右键显示于底层或颜色与父容器一致. 解决办法: 修改隐藏属性或右键显示于顶层. 2.灵活运用右键锁定控件与解锁控件. 3.注意 ...

  4. 图论---POJ 3660 floyd 算法(模板题)

    是一道floyd变形的题目.题目让确定有几个人的位置是确定的,如果一个点有x个点能到达此点,从该点出发能到达y个点,若x+y=n-1,则该点的位置是确定的.用floyd算发出每两个点之间的距离,最后统 ...

  5. spring框架(3)— spring集合类的注入

    1.Car.java package com.eniac.beans; public class Car { private String type; private String factory; ...

  6. week1:个人博客作业

    1.软件工程课程的希望和目标 老师步置的任务完整的做完,每一步都是自己做的,明白自己做的每一步,和为什么这样做. 期末考试最后为95分以上,最好是100. 每周学习这门课时间 每周2节课(90分钟)+ ...

  7. TCP系列51—拥塞控制—14、TLP、ER与拥塞控制

    一.概述 这里的重点是介绍TLP.ER与拥塞控制并不是介绍TLP和ER本身,因此TLP和ER的详细内容请翻前文. 在TLP与拥塞控制的交互中有几个点需要注意 1.TLP触发的重传后,TCP仍然处于Op ...

  8. Delphi通过ADO链接数据库及对数据库的增加,删除,修改,读取操作实例教程4

    ADO是一种程序对象,用于表示用户数据库中的数据结构和所包含的数据.ADO(ActiveXDataObjects,ActiveX数据对象)是Microsoft提出的应用程序接口(API)用以实现访问关 ...

  9. 【移动端debug-3】部分安卓机型不触发touchend事件的解决方案

    最近在项目中遇到一个奇怪的问题,有一个需求是这样:页面上有一个按钮,滚动页面时让它消失,停止滚动时让它显示. 常规思路: step1.监听touchstart事件,记录Touch对象中pageY初始值 ...

  10. RxSwift基本使用(一)

    备注:本文参考自田腾飞博文 [RxSwift入坑解读-你所需要知道的各种概念] (http://www.codertian.com/2016/11/27/RxSwift-ru-keng-ji-read ...