spoj 1825 Free tour II
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的更多相关文章
- SPOJ 1825 Free tour II (树的点分治)
题目链接 Free tour II 题意:有$N$个顶点的树,节点间有权值, 节点分为黑点和白点. 找一条最长路径使得 路径上黑点数量不超过K个 这是树的点分治比较基本的题,涉及树上启发式合并……仰望 ...
- SPOJ 1825 Free tour II 树分治
题意: 给出一颗边带权的数,树上的点有黑色和白色.求一条长度最大且黑色节点不超过k个的最长路径,输出最长的长度. 分析: 说一下题目的坑点: 定义递归函数的前面要加inline,否则会RE.不知道这是 ...
- 【SPOJ】1825. Free tour II(点分治)
http://www.spoj.com/problems/FTOUR2/ 先前看了一会题解就自己yy出来了...对拍过后交tle.................. 自己造了下大数据........t ...
- SPOJ:Free tour II (树分治+启发式合并)
After the success of 2nd anniversary (take a look at problem FTOUR for more details), this 3rd year, ...
- SPOJ FTOUR2 - Free tour II
Description 有些黑点,问你选择不超过 \(k\) 个黑点的路径,路径权值最大是多少. Sol 点分治. 这是qzc的论文题,不过我感觉他的翻译好强啊...我还是选择了自己去看题目... 点 ...
- [spoj] FTOUR2 FREE TOUR II || 树分治
原题 给出一颗有n个点的树,其中有M个点是拥挤的,请选出一条最多包含k个拥挤的点的路径使得经过的权值和最大. 正常树分治,每次处理路径,更新答案. 计算每棵子树的deep(本题以经过拥挤节点个数作为d ...
- SPOJ 1825 Free Tour | 终极之树分治
求树上最长路径使得经过的拥挤节点个数不超过K //欢迎访问这个博客!http://www.cnblogs.com/luyouqi233/p/8036828.html #include<cstdi ...
- SPOJ1825 FTOUR2 - Free tour II
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
- 后缀自动机(SAM):SPOJ Longest Common Substring II
Longest Common Substring II Time Limit: 2000ms Memory Limit: 262144KB A string is finite sequence of ...
随机推荐
- Spring – 缓存注解
Spring缓存抽象概述 Spring框架自身并没有实现缓存解决方案,但是从3.1开始定义了org.springframework.cache.Cache和org.springframework.ca ...
- EF 联合查询
EF 文章表和标签表联合查询标签id在dis中的文章,还不知道性能如何 var query = tagRepo.Entities.Include("Tags").Where(t = ...
- Java实现的词频统计——单元测试
前言:本次测试过程中发现了几个未知字符,这里将其转化为十六进制码对其加以区分. 1)保存统计结果的Result文件中显示如图: 2)将其复制到eclipse环境下的切分方法StringTokenize ...
- PHP用抛物线的模型实现微信红包生成算法的程序源码
<?php /* *Author:Kermit *Time:2015-8-26 *Note:红包生成随机算法 */ header("Content-type:text/html;cha ...
- webgl学习笔记二-绘图多点
写在前面 建议先看下第一篇webgl学习笔记一-绘图单点 第一篇文章,介绍了如何用webgl绘图一个点.接下来本文介绍的是如何绘制多个点.形成一个面. webgl提供了一种很方便的机制,即缓冲区对象, ...
- Shell Script的默认变量
$? #上一个命令执行后所回传的值,当我们执行某些命令时,这些命令都会回传一个执行后的代码.一般来说,如果成功执行该命令则会回传一个0值.如果执行过程发生错误,就会回传“错误代码” $$ #代表目前这 ...
- JavaScript常用方法(工具类的封装)
日期格式化 function formatDateTime(timeStamp) { var date = new Date(); date.setTime(timeStamp); var y = d ...
- 【Python】python操作mysql
pymysql模块对mysql进行 import pymysql # 创建连接 conn = pymysql.connect(host=, user='root', passwd='root', db ...
- USB硬件接口相关
1.USB 设备端的D+为何要拉一个1.5K电阻到3.3v上?(USB是5v供电,但通信的电平是3.3v,所以上拉电平为3.3v:若要上拉到5v,则上拉电阻为10k) usb有主从设备之分,主设备有: ...
- bzoj1007-水平可见直线
题目 在平面直角坐标系上以\(y=kx+b\)的形式给出\(n (n\le 50000)\)条直线,求从无限高的地方能看到多少条直线. 分析 举几个例子发现我们要求的直线组成一个下凸的形状.所以我们只 ...