当前位置: 首页 > 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.zskr.cn/news/3907.html

相关文章:

  • 突发!美国将复旦微等23家中国实体列入“实体清单”
  • [GenAI] Function Calling
  • 到底该用 KPI 还是 OKR ?
  • 9.13CSP-S Day6 模拟赛
  • 了解一下Redis Stack扩展功能
  • 游戏运行库合集 集成VC++、.NET、DirectX、XNA等千款组件,一键安装游戏必备依赖库 - 指南
  • 【CE】图形化CE游戏教程通关手册 - 详解
  • Python 潮流周刊#119:Google 停止开发 Pytype!
  • 单个光子的行为、传播特性、物质相互作用及其应用就是[光学原理与应用-449]:量子光学 - 量子光学研究的
  • 和为 K 的子数组-leetcode
  • 《10人以下小团队管理手册》读后感
  • GZHOIOJ律(一)
  • Kali Linux 虚拟机安装(VMware Workstation 17)
  • lilctf 部分wp - Elma
  • Selenium应用中的核心JavaScript操作技巧
  • 双重map 的赋值初始化
  • 0voice-1.4.1
  • AI踩坑之Nlog使用
  • 论文解读-《OpenGSL A Comprehensive Benchmark for Graph Structure Learning》 - zhang
  • Git 生成 ssh key
  • 一生一芯学习:pa2.1 RTFM
  • 一行代码没写,做了一个小程序
  • copyparty 是一款使用单个 Python 材料实现的内网文件共享软件,具有跨平台、低资源占用等特点,适合需要本地化文件管理的场景
  • 电商系统的Mysql表设计是怎么样呢
  • Docker应用 - CloudSaver
  • Web 3
  • Cursor小程序实战系列一:0到1开发一个小程序,需求整理、小程序注册备案
  • 赛题
  • .gitignore 文件
  • MySQL集群高可用架构 - 指南