Solution

二分答案, 尽量往上跳, 不能跳到根节点.

仍然能跳的拿出来.看剩下的点没有覆盖哪个?

贪心的分配一下.

Code

70

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int N = 50005; int n, m; struct Edge {
int v, c; Edge* nxt;
Edge(int _, int __, Edge* ___) :
v(_), c(__), nxt(___) {}
} *head[N];
void AddEdge(int u, int v, int c) {
head[u] = new Edge(v, c, head[u]);
head[v] = new Edge(u, c, head[v]);
} int f[N][18], p[N]; long long dis[N][18]; void dfs(int u, int fa, long long distan) {
f[u][0] = fa, dis[u][0] = distan;
for (int i = 1; i <= 17; i += 1) {
f[u][i] = f[f[u][i - 1]][i - 1];
dis[u][i] = dis[u][i - 1] + dis[f[u][i - 1]][i - 1];
}
for (auto edge = head[u]; edge; edge = edge->nxt) {
if (edge->v != fa)
dfs(edge->v, u, edge->c);
}
}
struct node {
node() {}
long long rest; int id;
node(int _id, int _r) :
id(_id), rest(_r) {}
bool operator < (const node& o) const {
return rest < o.rest;
}
} a[N], b[N]; int vis[N], used[N], R[N];
long long Min[N];
int A, B; int Dfs(int u, int fa) {
int f1 = true, noleaf = false;
if (vis[u]) return true;
for (auto edge = head[u]; edge; edge = edge->nxt) {
if (edge->v == fa) continue;
noleaf = true;
if (not Dfs(edge->v, u)) {
f1 = 0;
if (u == 1)
b[B++] = node(edge->v, edge->c);
else return false;
}
}
if (not noleaf) return false;
return f1;
} int check(long long lim) {
int u, now;
long long num;
A = B = 0;
for (int i = 1; i <= n; i += 1) vis[i] = 0;
for (int i = 1; i <= n; i += 1) R[i] = 0;
for (int i = 1; i <= m; i += 1) used[i] = 0;
for (int i = 1; i <= m; i += 1) {
u = p[i], num = 0;
for (int j = 17; ~j; j -= 1)
if (f[u][j] > 1 and num + dis[u][j] <= lim)
num += dis[u][j], u = f[u][j];
if (f[u][0] == 1 and num + dis[u][0] <= lim) {
a[A++] = node(i, lim - num - dis[u][0]);
if (not R[u] or a[A].rest < Min[u])
Min[u] = a[A].rest, R[u] = i;
} else vis[u] = 1;
}
if (Dfs(1, 0)) return true;
sort(a, a + A);
sort(b, b + B);
now = 0, used[0] = 1;
for (int i = 0; i < B; i += 1) {
if (!used[R[b[i].id]]) {
used[R[b[i].id]] = 1; continue;
}
while (now < A and (used[a[now].id] or a[now].rest < b[i].rest)) now += 1;
if (now >= A) return false;
used[a[now].id] = true;
}
return 1;
} int main() {
scanf("%d", &n);
for (int i = 1, u, v, c; i < n; i += 1) {
scanf("%d%d%d", &u, &v, &c);
AddEdge(u, v, c);
}
dfs(1, 0, 0);
scanf("%d", &m);
int l = 0, r = 5e5, mid;
for (int i = 1; i <= m; i += 1) scanf("%d", &p[i]);
while (l <= r) {
mid = l + r >> 1;
if (check(mid)) r = mid - 1;
else l = mid + 1;
}
printf("%d\n", l);
return 0;
}

最新文章

  1. JS实战 &#183; 复选框全选操作
  2. grunt不是内部或外部命令错误处理
  3. CentOS 6.7 中安装Emacs 24.5
  4. 【poj1160】 Post Office
  5. 设计模式之构建者模式(Builder):初步理解
  6. Android判断横屏竖屏代码
  7. work8
  8. hibernate动态创建数据库表名几种方式
  9. jquery validate.js表单验证的基本用法入门
  10. protobuf的反射机制
  11. Python httplib学习
  12. python 编码转换(转)
  13. 访问WEB-INF下的jsp/html
  14. ocs的沟通平台
  15. Bellman-Ford 求含负权最短路
  16. C# 枚举使用和对应说明获取实例
  17. MySQL/Oracle数据库优化总结
  18. 使用curl上传图片的方法
  19. EOJ 306 树上问题
  20. 关于djangorestframework相关源码分析

热门文章

  1. Eclipse开发Java代码,如何添加智能提示
  2. 【BZOJ3566】概率充电器(动态规划)
  3. 【CF813E】Army Creation(主席树)
  4. SQLite中的自增关键字:AUTO_INCREMENT、INTEGER PRIMARY KEY与AUTOINCREMENT
  5. bzoj4010: [HNOI2015]菜肴制作(拓扑排序+贪心+堆)
  6. vmware中无法ping通主机的问题
  7. OpenCV---高斯模糊(均值模糊的另一种)
  8. OpenCV---环境安装和初次使用
  9. React读取Excel——js-xlsx 插件的使用
  10. NOIP模拟3