记录编号 365096 评测结果 AAAAAAAAAAAAAAAAAAAAA
题目名称 [SPOJ 1825] 免费旅行II 最终得分 100
用户昵称 Gravatar‎MistyEye 是否通过 通过
代码语言 C++ 运行时间 3.918 s
提交时间 2017-01-19 16:53:00 内存使用 9.85 MiB
显示代码纯文本
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 200005;
struct Edge {
	int next, to, dis;
	Edge(int a=0, int b=0, int c=0) :
		next(a), to(b), dis(c) {}
} e[maxn<<1];
int head[maxn], tot;
void Add(int u, int v, int w) {
	e[++tot] = Edge(head[u], v, w); head[u] = tot;
}
int N, K, M, size[maxn], F, Size, root;
bool bk[maxn], vis[maxn];
int dep[maxn], Dep, son;
Edge t[maxn];
void getD(int x, int fa, int b, int &D) {
	D = max(b, D);
	for(int i=head[x]; i; i=e[i].next) {
		int to = e[i].to;
		if(vis[to] || to==fa) continue;
		getD(to, x, b+bk[to], D);
	}
}
void getdep(int x, int fa, int b, int d, int &ans, bool BK) {
	if(b+BK>K) return; //warn
	ans = max(ans, d+dep[min(K-b-BK, Dep)]);
	for(int i=head[x]; i; i=e[i].next) {
		int to = e[i].to;
		if(vis[to] || to==fa) continue;
		getdep(to, x, b+bk[to], d+e[i].dis, ans, BK);
	}
} 
void givediff(int x, int fa, int b, int d) {
	dep[b] = max(dep[b], d);
	for(int i=head[x]; i; i=e[i].next) {
		int to = e[i].to;
		if(vis[to] || to==fa) continue;
		givediff(to, x, b+bk[to], d+e[i].dis);
	}
}
bool cmp(const Edge &x, const Edge &y) { return x.next < y.next; }
void calc(int x, int &ans) {
	Dep = son = 0; dep[0] = 0;
	for(int i=head[x]; i; i=e[i].next) {
		int to = e[i].to;
		if(vis[to]) continue;
		t[++son] = Edge(0, to, e[i].dis);
		getD(to, x, bk[to], t[son].next); 
	} 
	sort(t+1, t+son+1, cmp); 
	for(int i=1; i<=son; ++i) { 
		int to = t[i].to; 
		getdep(to, x, bk[to], t[i].dis, ans, bk[x]); 
		givediff(to, x, bk[to], t[i].dis); 
		Dep = max(Dep, t[i].next);
		for(int j=1; j<=Dep; ++j) 
			dep[j] = max(dep[j], dep[j-1]);
	} 
	for(int i=0; i<=Dep; ++i) dep[i] = 0; 
} 
int getroot(int x, int fa) {
	int f = 0; size[x] = 1;
	for(int i=head[x]; i; i=e[i].next) {
		int to = e[i].to;
		if(vis[to] || to==fa) continue;
		size[x] += getroot(to, x);
		f = max(f, size[to]);
	}
	f = max(f, Size-size[x]);
	if(f<=F) F = f, root = x;
	return size[x];
}
int solve(int x, int &ans) {
	vis[x] = 1; calc(x, ans);
	for(int i=head[x]; i; i=e[i].next) {
		int to = e[i].to;
		if(vis[to]) continue;
		F = Size = size[to]; getroot(to, x);
		solve(root, ans);
	}
	return ans;
}
int main() {
	freopen("freetourII.in","r",stdin);
	freopen("freetourII.out","w",stdout);
	scanf("%d%d%d", &N, &K, &M);
	for(int i=1,a; i<=M; ++i) 
		scanf("%d", &a), bk[a] = 1;
	for(int i=1,a,b,c; i<N; ++i) {
		scanf("%d %d %d", &a, &b, &c);
		Add(a, b, c); Add(b, a, c);
	}
	F = Size = N; getroot(1, 0);
	int ans = 0; solve(root, ans);
	printf("%d\n", ans);
	getchar(), getchar();
	return 0;
}