记录编号 226679 评测结果 AAAAAAAAAAAAAAAAAAAAA
题目名称 [SPOJ 1825] 免费旅行II 最终得分 100
用户昵称 Gravatarstone 是否通过 通过
代码语言 C++ 运行时间 9.458 s
提交时间 2016-02-18 10:31:51 内存使用 13.67 MiB
显示代码纯文本
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 200000 + 5;
const int inf = 1e9;

int ans = -inf;
int n, k, m, sum, max_size, cnt;
int head[N], depth[N], fa[N], d[N];
int size[N], que[N], c[N], tmp[N<<1];
int tmp_cnt = 0;
bool vi[N], flag[N];

struct Edge {
  int from, to, dis, next;
}edges[N<<1];

void insert(int from, int to, int dis) {
  ++ cnt;
  edges[cnt].from = from;
  edges[cnt].to = to;
  edges[cnt].dis = dis;
  edges[cnt].next = head[from];
  head[from] = cnt;
}

void change(int pos) {
  for(int i = pos; i <= k + 2; i += (i & (-i))) {
	c[i] = -inf;
  }
}
int query(int x) {
  int res = -inf;

  for(int i = x; i > 0; i -= (i & (-i))) {
	res = max(res, c[i]);
  }
  return res;
}

void update(int pos, int val) {
  for(int i = pos; i <= k + 2; i += (i & (-i))) {
	c[i] = max(c[i], val);
  }
}

void getg(int u, int f, int &rt) {
  int maxx = 0;

  size[u] = 1;
  for(int i = head[u]; i; i = edges[i].next) {
	int v = edges[i].to;

	if(!vi[v] && v != f) {
	  getg(v, u, rt);
	  size[u] += size[v];
	  maxx = max(size[v], maxx);
	}
  }
  maxx = max(sum - maxx, maxx);
  if(maxx < max_size) {
	max_size = maxx;
	rt = u;
  }
}

void calc(int u) {
  for(int i = head[u]; i; i = edges[i].next) {
	int v = edges[i].to;

	if(vi[v]) continue;

	int h = 1, t = 1;

	que[h] = v; fa[v] = u;
	d[v] = edges[i].dis;
	depth[v] = flag[v];
	while(h <= t) {
	  int x = que[h];

	  for(int j = head[x]; j; j = edges[j].next) {
		int to = edges[j].to;

		if(!vi[to] && to != fa[x]) {
		  fa[to] = x;
		  d[to] = d[x] + edges[j].dis;
		  depth[to] = depth[x] + flag[to];
		  que[++ t] = to;
		}
	  }
	  ++ h;
	}
	for(int j = 1; j <= t; ++ j) {
	  int x = que[j];

	  if(depth[x] <= k) {
		int lmd = query(k - depth[x] + 1);

		ans = max(d[x] + lmd, ans);
		ans = max(ans, d[x]);
	  }
	}
	for(int j = 1; j <= t; ++ j) {
	  int x = que[j];

	  if(depth[x] <= k) {
		update(depth[x] + 1, d[x]);
		tmp[++ tmp_cnt] = depth[x] + 1;
	  }
	}
  }
  for(int i = 1; i <= tmp_cnt; ++ i)
	change(tmp[i]);
  tmp_cnt = 0;
}

void solve(int u) {
  int rt;

  max_size = n + 1;
  getg(u, 0, rt);
  u = rt;
  if(flag[u]) k --;
  calc(u);
  if(flag[u]) k ++;
  vi[u] = true;
  for(int i = head[u]; i; i = edges[i].next) {
	int v = edges[i].to;

	if(!vi[v]) {
	  sum = size[v];
	  solve(v);
	}
  }
}

int qread() {
  int x = 0; char ch = getchar();

  while(ch > '9' || ch < '0') ch = getchar();
  while(ch <= '9' && ch >= '0') {
	x = x * 10 + ch - '0';
	ch = getchar();
  }
  return x;
}

int main() {
  int __size__ = 64 << 20;
  char *__p__ = (char*)malloc(__size__) + __size__;
  __asm__("movl %0, %%esp\n" :: "r"(__p__));

#ifndef ONLINE_JUDGE
  freopen("freetourII.in", "r", stdin);
  freopen("freetourII.out", "w", stdout);
#endif
  
  int u, v, w;
  
  n = qread(); k = qread(); m = qread();
  for(int i = 1; i <= m; ++ i) {
	scanf("%d", &u);
	flag[u] = true;
  }
  for(int i = 1; i < n; ++ i) {
	u = qread(); v = qread();
	scanf("%d", &w);
	insert(u, v, w); insert(v, u, w);
  }
  for(int i = 1; i <= k + 1; ++ i)
	c[i] = -inf;
  sum = n;
  solve(1);
  printf("%d\n", ans == -inf ? 0 : ans);
#ifndef ONLINE_JUDGE
  fclose(stdin); fclose(stdout);
#endif
  return 0;
}