记录编号 | 467472 | 评测结果 | AAAAAAAAAA | ||
---|---|---|---|---|---|
题目名称 | [NOIP 2012]疫情控制 | 最终得分 | 100 | ||
用户昵称 | 是否通过 | 通过 | |||
代码语言 | 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; }