=。=
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define max(a, b) (a) > (b) ? (a) : (b)
inline void read(int &x) {
x = 0;
char c = getchar();
while(c<'0'||c>'9') c = getchar();
while(c>='0'&&c<='9') x = x * 10 + c - '0', c = getchar();
return;
}
const int maxn = 300010;
int n, m, tot,last[maxn],dis[maxn],top[maxn],father[maxn],son[maxn];
int edge_back_father[maxn],deep[maxn],upline,tag[maxn],dmax,wmax,downline;
struct ASK{
int u,v,dis,lca;
}ask[maxn];
struct Edge{
int u,v,w,to;
Edge(){}
Edge(int u, int v, int w, int to) : u(u), v(v), w(w), to(to) {};
}e[maxn*2+6];
void addedge(int u, int v, int w) {
e[++tot] = Edge(u,v,w,last[u]);
last[u] = tot;
}
void dfs1(int x) {
son[x] = 1;
deep[x] = deep[father[x]] + 1;
for(int i=last[x]; i; i=e[i].to) {
if(e[i].v != father[x]) {
father[e[i].v] = x;
int v = e[i].v;
edge_back_father[v] = i;
dis[v] = dis[x] + e[i].w;
dfs1(v);
son[x] += son[v];
}
}
}
void dfs2(int x) {
int t=0;
if(!top[x]) top[x] = x;
for(int i=last[x]; i; i=e[i].to)
if(e[i].v!=father[x] && son[e[i].v] > son[t]) t = e[i].v;
if(t) top[t] = top[x];
for(int i=last[x]; i; i=e[i].to)
if(e[i].v!=father[x]) dfs2(e[i].v);
}
inline int lca(int x, int y) {
while(top[x] != top[y]) {
if(deep[top[x]] < deep[top[y]]) std::swap(x, y);
x = father[top[x]];
}
return (deep[x] > deep[y]) ? y : x;
}
void dfs_date(int x) {
for(int i=last[x]; i; i=e[i].to) {
if(e[i].v != father[x]) {
dfs_date(e[i].v);
tag[x] += tag[e[i].v];
}
}
}
bool check(int x) {
int dec=0 , cnt=0;
memset(tag, 0, sizeof(tag));
for(int i=1; i<=m; i++) {
if(ask[i].dis > x) {
dec = max(dec, ask[i].dis - x);
tag[ask[i].u]++;
tag[ask[i].v]++;
tag[ask[i].lca] -= 2;
cnt++;
}
}
dfs_date(1);
for(int i=1; i<=n; i++)
if(cnt == tag[i] && e[edge_back_father[i]].w >= dec)
return true;
return false;
}
inline int div() {
int l = downline, r = upline, ans = 0;
while(l <= r) {
int mid = l + r >> 1;
if(check(mid)) r = mid - 1, ans = mid;
else l = mid + 1;
}
return ans;
}
int main(){
read(n);read(m);
for(int i=1,u,v,w; i<n; i++) {
read(u); read(v); read(w);
addedge(u,v,w);
addedge(v,u,w);
wmax = max(wmax,w);
}
dfs1(1);
dfs2(1);
for(int i=1; i<=m; i++) {
read(ask[i].u);
read(ask[i].v);
ask[i].lca = lca(ask[i].u, ask[i].v);
ask[i].dis = dis[ask[i].u] + dis[ask[i].v] - 2*dis[ask[i].lca];
upline = max(upline, ask[i].dis);
dmax = max(dmax, ask[i].dis);
}
downline = dmax - wmax;
printf("%d",div());
return 0;
}

本文介绍了一种基于图论的算法优化方法,通过构建复杂的图结构来解决特定问题。使用深度优先搜索和动态规划等技术,实现了对路径查找、距离计算等问题的有效处理。
2183

被折叠的 条评论
为什么被折叠?



