记录编号 467472 评测结果 AAAAAAAAAA
题目名称 [NOIP 2012]疫情控制 最终得分 100
用户昵称 GravatarAAAAAAAAAA 是否通过 通过
代码语言 C++ 运行时间 0.337 s
提交时间 2017-10-30 17:31:52 内存使用 3.40 MiB
显示代码纯文本
#define _CRT_SECURE_NO_WARNINGS
#include<cstdio>
#include<bitset>
#include<algorithm>
#include<vector>
#include<cstring>
#define MAXN 50010
namespace IO {
	char buf[1 << 15], *fs, *ft;
	inline char gc() { return (fs == ft && (ft = (fs = buf) + fread(buf, 1, 1 << 15, stdin), fs == ft)) ? 0 : *fs++; }
	inline int qr() {
		int x = 0, rev = 0, ch = gc();
		while (ch<'0' || ch>'9') { if (ch == '-')rev = 1; ch = gc(); }
		while (ch >= '0'&&ch <= '9') { x = (x << 1) + (x << 3) + ch - '0'; ch = gc(); }
		return rev ? -x : x;
	}
}using namespace IO;
using namespace std;
struct Edge {
	int t, next, v;
}e[MAXN << 1];
int head[MAXN], cnt;
void Add_Edge(int from, int to, int val) {
	e[++cnt].t = to; e[cnt].next = head[from]; head[from] = cnt; e[cnt].v = val;
	e[++cnt].t = from; e[cnt].next = head[to]; head[to] = cnt; e[cnt].v = val;
}
int N, M, fa[MAXN], dep[MAXN], son[MAXN], top[MAXN], siz[MAXN], deg[MAXN];
void DFS1(int u) {
	siz[u] = 1;
	for (int i = head[u]; i; i = e[i].next) {
		int v = e[i].t;
		if (v == fa[u])continue;
		dep[v] = dep[u] + e[i].v; fa[v] = u;
		DFS1(v); siz[u] += siz[v];
		if (siz[v]>siz[son[u]])son[u] = v;
	}
}
void DFS2(int u, int tp) {
	top[u] = tp;
	if (son[u])DFS2(son[u], tp);
	for (int i = head[u]; i; i = e[i].next) {
		int v = e[i].t;
		if (v != fa[u] && v != son[u])DFS2(v, v);
	}
}
int pos[MAXN], bel[MAXN], used[MAXN];
bitset<MAXN>vis;
typedef pair<int, int> pa;
vector<pa>a;
vector<pa>b;
void Work(int x, int tim) {
	int tp = top[x];
	while (fa[tp]&&dep[x] - dep[fa[tp]] <= tim) {
		tim -= dep[x] - dep[fa[tp]];
		x = fa[tp]; tp = top[x];
	}
	while (dep[x] - dep[fa[x]] <= tim) {
		tim -= dep[x] - dep[fa[x]];
		x = fa[x];
	}
	vis[x] = 1;
}
bool DFS3(int u, int root) {
	bel[u] = root;
	if (deg[u] == 1)return 1;
	bool flag = 0;
	for (int i = head[u]; i; i = e[i].next) {
		int v = e[i].t;
		if (v != fa[u] && !vis[v])flag |= DFS3(v, root);
	}
	return flag;
}
bool Check(int mid) {
	vis.reset(); memset(used, 0, sizeof(used)); a.clear(); b.clear();
	for (int i = 1; i <= M; i++) {
		if (dep[pos[i]]>mid)Work(pos[i], mid);
		else {
			int res = mid - dep[pos[i]];
			a.push_back(make_pair(res, pos[i]));
			used[pos[i]]++;
		}
	}
	for (int i = head[1]; i; i = e[i].next) {
		int v = e[i].t;
		if (!vis[v]&&DFS3(v, v))b.push_back(make_pair(e[i].v, v));
		else vis[v] = 1;
	}
	int lena = a.size(), lenb = b.size();
	//if (lena<lenb)return 0;
	for (int i = 0; i<lena; i++) {
		if (!vis[bel[a[i].second]] && a[i].first <= dep[bel[a[i].second]]&&used[a[i].second]) {
			used[a[i].second] --; vis[bel[a[i].second]] = 1;
		}
	}
	sort(a.begin(), a.end());
	sort(b.begin(), b.end());
	int i = 0, j = 0;
	while (i<lena&&j<lenb) {
		if (a[i].first >= b[j].first && !vis[b[j].second] && used[a[i].second]) { used[a[i].second]--; j++; i++; }
		else if (vis[b[j].second])j++;
		else i++;
	}
	while (j < lenb&&vis[b[j].second])j++;
	if ((j<lenb&&i<lena) || j >= lenb)return 1;
	else return 0;
}
int x, y, z;
int main() {
	freopen("blockade.in", "r", stdin);
	freopen("blockade.out", "w", stdout);
	N = qr();
	for (int i = 1; i<N; i++) {
		x = qr(); y = qr(); z = qr();
		Add_Edge(x, y, z);
		deg[x]++; deg[y]++;
	}
	DFS1(1); DFS2(1, 1);
	M = qr();
	for (int i = 1; i <= M; i++)pos[i] = qr();
	if (M<deg[1]) {
		printf("-1");
		return 0;
	}
	int l = 0, r = 5e7, ans;
	while (l <= r) {
		int mid = (l + r) >> 1;
		if (Check(mid))ans = mid, r = mid - 1;
		else l = mid + 1;
	}
	printf("%d", ans);
	return 0;
}