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. ubuntu上完全卸载package

    inux上完整的卸载apt方式安装软件的办法. 假设你的包叫做: your_pkg apt-get --purge remove your_pkg apt-get autoremove apt-get ...

  2. BeautifulSoup获取指定class样式的div

    如何获取指定的标签的内容是解析网页爬取数据的必要手段,比如想获取<div class='xxx'> ...<div>这样的div标签,通常有三种办法, 1)用字符串查找方法,然 ...

  3. 在CentOS 6.4中编译安装gcc 4.8.1

    在CentOS 6.4中编译安装gcc 4.8.1 分类: C/C++ Linux/Unix2013-11-28 21:02 1877人阅读 评论(0) 收藏 举报 原文链接:http://www.c ...

  4. 【Hibernate】Hibernate系列8之管理session

    管理session 更简单的,注入对象:

  5. JVM调优浅谈

    1.数据类型 java虚拟机中,数据类型可以分为两类:基本类型和引用类型.基本类型的变量保存原始值,即:它代表的值就是数值本身,而引用类型的变量保存引用值.“引用值”代表了某个对象的引用,而不是对象本 ...

  6. MVC ViewBag和ViewData的区别

    在MVC3开始,视图数据可以通过ViewBag属性访问,在MVC2中则是使用ViewData.MVC3中保留了ViewData的使用.ViewBag 是动态类型(dynamic),ViewData 是 ...

  7. 高效PHP开发注意事项

    2015年2月26日 17:23:26 http://www.open-open.com/lib/view/open1332904714233.html

  8. Linux下挂载NTFS格式的U盘或硬盘

    我们知道在Linux下挂载fat32的U盘非常容易,使用mount /dev/drive_name /mnt/指定目录这样就可以挂载了,但是如果U盘或者硬盘的格式是NTFS的话,那么Linux是不能识 ...

  9. NEFU 1146 又见A+B

    又见a+b Problem:1146 Time Limit:1000ms Memory Limit:65535K Description 给定两个非负整数A,B,求他们的和. Input 多组输入,每 ...

  10. Fedora 启动sshd服务:

    .先确认是否已安装ssh服务: [root@localhost ~]# rpm -qa | grep openssh-server openssh-server-.3p1-.fc12.i686 (这行 ...