MnZn刚学树上差分50pts求助
查看原帖
MnZn刚学树上差分50pts求助
503792
Svemit楼主2023/10/11 21:52

rt

#include <bits/stdc++.h>
#define fi first
#define se second
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
const int N = 3e5 + 5, INF = 0x3f3f3f3f;
const LL mod = 1e9 + 7;
int n, m;
vector<PII> e[N];
int dist[N], dep[N], d[N];
int fa[N][20];
struct path {
	int u, v, p, d;
} q[N];
void dfs(int u, int fath) {
	dep[u] = dep[fath] + 1;
	fa[u][0] = fath;
	for(int i = 1; i <= __lg(dep[u]); i ++)
	 	fa[u][i] = fa[fa[u][i - 1]][i - 1];
	for(auto t : e[u]) {
		int v = t.fi, w = t.se;
		if(v == fath) continue;
		dist[v] = dist[u] + w;
		dfs(v, u);
	}
}
int lca(int u, int v) {
	if(dep[u] < dep[v]) swap(u, v);
	while(dep[u] != dep[v]) u = fa[u][__lg(dep[u] - dep[v])];
	if(u == v) return u;
	for(int k = __lg(dep[u]); ~k; k --)
		if(fa[u][k] != fa[v][k]) 
			u = fa[u][k], v = fa[u][k];
	return fa[u][0];
}
void dfs_d(int u) {
	for(auto t : e[u]) if(t.fi != fa[u][0]) 
		dfs_d(t.fi), d[u] += d[t.fi];
}
bool check(int x) {
	memset(d, 0, sizeof d);
	int cnt = 0, mx = 0;
	for(int i = 1; i <= m; i ++)
		if(q[i].d > x) {
			cnt ++;
			mx = max(mx, q[i].d);
			d[q[i].u] ++, d[q[i].v] ++, d[q[i].p] -= 2;
		}
	if(!cnt) return true;
	dfs_d(1);
	for(int i = 1; i <= n; i ++) 
		if(d[i] == cnt && mx - (dist[i] - dist[fa[i][0]]) <= x) return true;
	return false; 
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr); cout.tie(nullptr);
	cin >> n >> m;
	for(int i = 1; i < n; i ++) {
		int u, v, w;
		cin >> u >> v >> w;
		e[u].push_back({v, w});
		e[v].push_back({u, w});
	}
	dfs(1, 0);
	for(int i = 1; i <= m; i ++) {
		cin >> q[i].u >> q[i].v;
		q[i].p = lca(q[i].u, q[i].v);
		q[i].d = dist[q[i].u] + dist[q[i].v] - 2 * dist[q[i].p];
	}
	int l = 0, r = 3e8, res;
	while(l <= r) {
		int mid = l + r >> 1;
		if(check(mid)) res = mid, r = mid - 1;
		else l = mid + 1;
	}
	cout << res << '\n';
    return 0;	
}
2023/10/11 21:52
加载中...