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

先前看了一会题解就自己yy出来了。。。对拍过后交tle。。。。。。。。。。。。。。。。。。

自己造了下大数据。。。。。。。。tle。。。。。。。。。。。。。。。。。。。。。。。。。

what?

首先来看经过当前点的路径:

设g[x,i]表示第x个孩子能得到的路径上黑点最多有i个(注意是最多)的最大长度,因为遍历的节点最坏为n个(第一层),因此在每一层都是$O(n)$的,可以承受。

考虑转移答案

$$ans[x]=max\{g[u,i]+g[v,k-black[x]-i], u!=v\}$$

这个方程似乎很显然?如果看不懂的请仔细思考所定义的状态,特别是“最多为i个”

可是最坏情况下有$n$个黑点,所以状态数目就有$n^2$了(尽管在每一层中有效转移状态仅仅为$O(n)$),而且暴力转移也是$O(n^2)$

考虑减少状态,试着去掉第一维。发现如果有序遍历每个子女时,之前遍历过的可以直接查找,而且每一次都是同样的操作(即查找之前子女的每一个状态),而转移是max,想到合并为一个状态。那么状态只剩$O(n)$

但是发现,如果k达到了$n$,那么我们在更新g值的话(更新g值就是从小的黑点更新大的黑点,即g[i]=max{g[j], j<=i},会tle成狗。。。。因为每次都要更新到k。。。。)

就是到这里我交了tle。。。。。。。。。。。。。。。。。。然后想不出来了。。。。。。。。。。。。。。。。。

做法:发现如果子女遍历黑点的深度是递增的话,因为每次更新g值不超过当前黑点深度,所以所有更新g值次数加起来均摊$O(n)$

排序子女深度$O(nlgn)$,因此本题总时间复杂度为$O(nlg^2n)$

#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
#define rep(i, n) for(int i=0; i<(n); ++i)
#define for1(i,a,n) for(int i=(a);i<=(n);++i)
#define for2(i,a,n) for(int i=(a);i<(n);++i)
#define for3(i,a,n) for(int i=(a);i>=(n);--i)
#define for4(i,a,n) for(int i=(a);i>(n);--i)
#define CC(i,a) memset(i,a,sizeof(i))
#define read(a) a=getint()
#define print(a) printf("%d", a)
#define dbg(x) cout << (#x) << " = " << (x) << endl
#define error(x) (!(x)?puts("error"):0)
#define rdm(x, i) for(int i=ihead[x]; i; i=e[i].next)
inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; } const int N=200005, oo=~0u>>1;
int ihead[N], cnt, n;
struct dat { int next, to, w; }e[N<<1];
inline void add(int u, int v, int w) {
e[++cnt].next=ihead[u]; ihead[u]=cnt; e[cnt].to=v; e[cnt].w=w;
e[++cnt].next=ihead[v]; ihead[v]=cnt; e[cnt].to=u; e[cnt].w=w;
}
int root, sz[N], vis[N], ans, h[N], blc[N], g[N], bsz[N], K, mn;
void getroot(int x, int fa, int sum) {
sz[x]=1; int mx=0, y;
rdm(x, i) if(!vis[y=e[i].to] && e[i].to!=fa) {
getroot(y, x, sum);
sz[x]+=sz[y];
mx=max(mx, sz[y]);
}
mx=max(mx, sum-mx);
if(mx<mn) mn=mx, root=x;
}
void cal(int x, int len, int num, int fa) {
h[num]=max(h[num], len); int y;
rdm(x, i) if(!vis[y=e[i].to] && e[i].to!=fa) {
cal(y, len+e[i].w, num+blc[y], x);
}
}
void fix(int len) {
int mx=-oo;
for1(i, 0, len) {
mx=max(mx, g[i]);
g[i]=mx;
}
}
void getbsz(int x, int fa) {
bsz[x]=blc[x];
rdm(x, i) if(!vis[e[i].to] && e[i].to!=fa) getbsz(e[i].to, x), bsz[x]+=bsz[e[i].to];
}
struct QQ {
int dep, id;
bool operator<(const QQ &a) const { return dep<a.dep; }
}q[N];
void dfs(int x, int sum) {
vis[x]=1;
int y, maxdep=-1, kk=K-blc[x];
int tot=0, pos;
rdm(x, i) if(!vis[y=e[i].to]) {
getbsz(y, x);
q[++tot].dep=bsz[y];
q[tot].id=i;
}
sort(q+1, q+1+tot);
for1(i, 1, tot) {
int now=q[i].id, y=e[now].to, s=min(q[i].dep, kk);
for1(j, 0, s) h[j]=-oo;
cal(y, e[now].w, blc[y], x);
if(i==1) for1(j, 0, s) g[j]=h[j];
else {
for1(j, 0, s) {
pos=kk-j; if(pos>maxdep) pos=maxdep;
if(g[pos]!=-oo && h[j]!=-oo) ans=max(g[pos]+h[j], ans);
}
for1(j, 0, s) g[j]=max(g[j], h[j]);
}
maxdep=s;
fix(maxdep);
}
ans=max(ans, g[min(kk, maxdep)]);
rdm(x, i) if(!vis[y=e[i].to]) {
int s=sz[y]>sz[x]?sum-sz[x]:sz[y];
root=0; mn=oo; getroot(y, x, s);
dfs(root, s);
}
}
int main() {
read(n); read(K); int m=getint();
for1(i, 1, m) blc[getint()]=1;
rep(i, n-1) { int u=getint(), v=getint(), w=getint(); add(u, v, w); }
mn=oo;
getroot((n+1)>>1, -1, n);
dfs(root, n);
print(ans);
return 0;
}

  


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 a tree 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 them crowded 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

Explanation

We choose 2 and 6 as the departure and destination place, so the tour will be 2 -> 3 -> 4 -> 5 -> 6, total interest value = 10 + (-2) + (-1) + 5 = 12

【SPOJ】1825. Free tour II(点分治)的更多相关文章

  1. SPOJ 1825 Free tour II 树分治

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

  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] FTOUR2 FREE TOUR II || 树分治

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

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

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

  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】Free tour II (点分治,启发式)

    题意: 边权可能为负 思路: 感觉我自己写的还是太过僵硬了,可以灵活一点,比如可以多写几个不同的dfs求出不同的信息,而不是压到同一个dfs里 #include<cstdio> #incl ...

随机推荐

  1. 什么是元数据(Metadata)?

    什么是元数据        任何文件系统中的数据分为数据和元数据.数据是指普通文件中的实际数据,而元数据指用来描述一个文件的特征的系统数据,诸如访问权限.文件拥有者以及文件数据块的分布信息(inode ...

  2. OpenGL实现三维立方体交互

    http://yunpan.cn/cs62JgxTNs98C  (提取码:668e)

  3. Django之admin界面恢复及添加数据模型

    引自:http://fl0wjacky.github.io/jekyll_demo/2014/07/14/Django-admin.html Django之admin界面恢复及添加数据模型 Djang ...

  4. Selenium webdriver 学习总结-元素定位

    Selenium webdriver 学习总结-元素定位 webdriver提供了丰富的API,有多种定位策略:id,name,css选择器,xpath等,其中css选择器定位元素效率相比xpath要 ...

  5. 25.在从1到n的正数中1出现的次数[NumberOf1Between1_N]

    [题目] 输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数.例如输入12,从1到12这些整数中包含1 的数字有1,10,11和12,1一共出现了5次. [分析] 这是一道广为流传的goo ...

  6. iOS 中的Push Notifications简单实现(APNS)

    Android中的通知只有一种,就是Local Notifications,而iOS中除了Local Notifications外,还有一种Push Notifications.ios的这2种noti ...

  7. 如何用OpenCV自带的adaboost程序训练并检测目标

    参考博文: 1.http://blog.csdn.net/wuxiaoyao12/article/details/39227189 2.http://www.cnblogs.com/easymind2 ...

  8. p168习题

  9. xampp 访问出现New XAMPP security concept

    在浏览器输入 http://60.10.140.22/xampp出现以下错误信息: Access forbidden! New XAMPP security concept: Access to th ...

  10. Grid画边框

    public class GridHelper { //请注意:可以通过propa这个快捷方式生成下面三段代码 public static bool GetShowBorder(DependencyO ...