当前位置: 首页 > news >正文

树上问题

运输计划

比较简单的题,9.13一遍过
首先比较容易想到二分,那么如何check呢,把所有大于mid的运输计划拎出来
这些之中应该找到他们交集中最大的一条,如果将他变成虫洞可以那就ok

#include <bits/stdc++.h>
#define rep(i, a, b) for(int i = (a); i <= (b); i ++ )
#define repf(i, a, b) for(int i = (a); i >= (b); i -- )
#define ls t[cur].lson
#define rs t[cur].rson
typedef unsigned long long ll;
using namespace std;
const int N = 3e5 + 10;
int n, m;
int head[N], nxt[N << 1], to[N << 1], w[N << 1], E;
int LCA[N], dis[N], dep[N], f[N][19];
struct node
{int x, y, d, lca;
}cm[N];
inline void add(int x, int y, int z)
{to[E] = y;nxt[E] = head[x];w[E] = z;head[x] = E ++;
}
void dfs(int u, int fa)
{for(int i = head[u]; ~i; i = nxt[i]){int x = to[i];if(x == fa) continue;dep[x] = dep[u] + 1, f[x][0] = u;rep(i, 1, 18) f[x][i] = f[f[x][i-1]][i-1];dis[x] = dis[u] + w[i];dfs(x, u);}
}
inline int lca(int x, int y)
{if(dep[x] < dep[y]) swap(x, y);int d = dep[x] - dep[y];repf(i, 18, 0) if( d & (1 << i) ) x = f[x][i];if(x == y) return x;repf(i, 18, 0) if(f[x][i] != f[y][i]) x = f[x][i], y = f[y][i];return f[x][0];
}
inline bool cmp(node n1, node n2) {return n1.d < n2.d;}
int c[N];
void ddd(int u, int fa)
{for(int i = head[u]; ~i; i = nxt[i]){int x = to[i];if(x == fa) continue;ddd(x, u);c[u] += c[x];}
}
inline bool check(int x)
{int l = 1, r = m, best = -1;while(l <= r){int mid = l + r >> 1;if(cm[mid].d > x) r = mid - 1, best = mid;else l = mid + 1;}if(best == -1) return 1;// best ~ mmemset(c, 0, sizeof c);int M = 0;rep(i, best, m) c[cm[i].x] ++, c[cm[i].y] ++, c[cm[i].lca] -= 2, M = max(M, cm[i].d);ddd(1, -1);int MM = 0;rep(i, 1, n) if(c[i] == m - best + 1) MM = max(MM, dis[i] - dis[f[i][0]]);return M - MM <= x;
}
int main()
{ios :: sync_with_stdio(0);cin.tie(0);cout.tie(0);memset(head, -1, sizeof head);cin >> n >> m;rep(i, 1, n - 1){int x, y, z; cin >> x >> y >> z;add(x, y, z); add(y, x, z);}dep[1] = 1; dfs(1, -1);rep(i, 1, m){cin >> cm[i].x >> cm[i].y;cm[i].lca = lca(cm[i].x, cm[i].y);cm[i].d = dis[cm[i].x] + dis[cm[i].y] - 2 * dis[cm[i].lca];}sort(cm + 1, cm + 1 + m, cmp);int l = 0, r = cm[m].d, best = -1;while(l <= r){int mid = l + r >> 1;if(check(mid)) r = mid - 1, best = mid;else l = mid + 1; }cout << best;return 0;
}

货车运输

首先小的边是能不走就不走的,所以先求出最大生成树
剩下就是求倍增求lca时顺便求出最边即可

[USACO10HOL] Cow Politics G

类比dfs求直径,先任取一个点x,求出距离x最远的点a,则a一定是直径的端点那么再求距离a的最远点即可
直径还有一些性质比如
一个点集的直径是x, y 现在加入一个点那么新的直径的一个端点必然是x或y。
合并两个点集,就是合并前的x->y, a->b(两条直径)这四个点的组合中必然有一条是直径

http://www.wxhsa.cn/company.asp?id=2967

相关文章:

  • 突发!美国将复旦微等23家中国实体列入“实体清单”
  • [GenAI] Function Calling
  • form表单
  • 【Zotero7】使用Attanger和百度同步空间如何进行同步?
  • XSS 漏洞挖掘学习
  • str
  • 到底该用 KPI 还是 OKR ?
  • 【重点!!!】必知必会必须掌握的serializers序列化器类之Serializer和ModelSerializer核心区别
  • StringUtils.isNotBlank和StringUtils.isNotEmpty的区别
  • ECT-OS-JiuHuaShan框架元推理,已在DeepSeek上实现agi
  • 9.13CSP-S Day6 模拟赛
  • 助教工作总结
  • 了解一下Redis Stack扩展功能
  • 游戏运行库合集 集成VC++、.NET、DirectX、XNA等千款组件,一键安装游戏必备依赖库 - 指南
  • 【CE】图形化CE游戏教程通关手册 - 详解
  • GZHOIOJ律(三)
  • visual studio 切换重载
  • [AGC022F] Checkers 题解
  • 程序员的副业变现之路:我的双平台矩阵打法
  • Python 潮流周刊#119:Google 停止开发 Pytype!
  • 利用k8s client-go库创建CRD的informer的操作流程
  • Golang并发编程及其高级特性
  • 单个光子的行为、传播特性、物质相互作用及其应用就是[光学原理与应用-449]:量子光学 - 量子光学研究的
  • 和为 K 的子数组-leetcode
  • 元推理agi不是象人思维,而是教人思维,人类脸上挂不住啊
  • 《10人以下小团队管理手册》读后感
  • GZHOIOJ律(二)
  • 优惠券
  • GZHOIOJ律(一)
  • 基于ArcGIS Pro SDK 3.4.2 + C# + .NET 8 的自动化制图系统初探