和别人口胡树链的交有点虚,于是写了一发大讨论….不同OJ评测结果不同我也不知算不算过了,反正有个OJ T了卡常死活卡不过去。。。
这道题可以选择二分,二分后有两种做法,一种最后复杂度是
O(nlogn)
(打标记dfs扫一遍),一种最后复杂度是
O(nlog2n)
(这个做法就多了)
也可以不二分,考虑一种贪心的做法:
先将所有航线排序,然后从第
m
条航线开始往前做树链的交,那么在位置
这样做复杂度是
mlogn
的,然而因为我写的树链的交可能常数特别大……有的OJ上并不能过所有点
code:
#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn = 301000;
const int maxl = 19;
struct edge
{
int y,c,nex;
edge(){}
edge(int _y,int _c,int _nex){y=_y;c=_c;nex=_nex;}
}a[maxn<<1]; int len,fir[maxn];
void ins(int x,int y,int c){a[++len]=edge(y,c,fir[x]);fir[x]=len;}
int n,m;
int fa[maxn][maxl],fs[maxn][maxl],dep[maxn];
int dis[maxn];
void up(int &x,int y){if(y>x)x=y;}
void dfs(int x)
{
for(int k=fir[x];k;k=a[k].nex)
{
int y=a[k].y;
if(y!=fa[x][0])
{
dis[y]=dis[x]+a[k].c;
dep[y]=dep[x]+1;
fa[y][0]=x; fs[y][0]=a[k].c;
dfs(y);
}
}
}
struct node
{
int x,y,Lca,c;
}q[maxn];
int g_lca(int x,int y)
{
if(x==y) return x;
if(dep[x]<dep[y]) swap(x,y);
if(dep[x]!=dep[y])
{
for(int i=maxl-1;i>=0;i--)
if(dep[x]-(1<<i)>=dep[y]) x=fa[x][i];
if(x==y) return x;
}
for(int i=maxl-1;i>=0;i--)
if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
return fa[x][0];
}
int gmx(int x,int y)
{
if(x==y) return 0;
int mx=0,dd=dep[y]-dep[x];
for(int i=maxl-1;i>=0;i--)
if((1<<i)<=dd) up(mx,fs[y][i]),y=fa[y][i],dd-=1<<i;
return mx;
}
bool cmp(node x,node y){return x.c<y.c;}
void solve(int &x1,int &y1,int &xy1,int x2,int y2,int xy2)
{
if(x2==xy2&&x1!=xy1){swap(x1,x2);swap(y1,y2);swap(xy1,xy2);}
if(x1==xy1)
{
if(x2==xy2)
{
int tx;
tx=g_lca(x1,y2);
if(tx==x1)
{
tx=g_lca(x2,y1);
if(tx==x2)
{
x1=dep[x1]>dep[x2]?x1:x2;
y1=g_lca(y1,y2);
xy1=x1;
return ;
}
}
}
else
{
int tx; tx=g_lca(x1,xy2);
if(tx==x1)
{
tx=g_lca(y1,xy2);
if(tx==xy2)
{
xy1=x1=xy2;
tx=g_lca(y1,x2);
y1=g_lca(y1,y2);
if(dep[tx]>dep[y1]) y1=tx;
return ;
}
}
else if(tx==xy2)
{
xy1=x1;
tx=g_lca(x1,x2);
if(tx==x1) { y1=g_lca(y1,x2); return ; }
tx=g_lca(x1,y2);
if(tx==x1) { y1=g_lca(y1,y2); return ; }
}
}
x1=-1; return ;
}
else
{
int tx;
if(xy1==xy2)
{
tx=g_lca(x1,y2);
x1=g_lca(x1,x2);
if(dep[tx]>dep[x1]) x1=tx;
tx=g_lca(y1,y2);
y1=g_lca(y1,x2);
if(dep[tx]>dep[y1]) y1=tx;
return ;
}
tx=g_lca(xy1,xy2);
if(tx==xy2) {swap(x1,x2); swap(y1,y2); swap(xy1,xy2);}
if(tx==xy1)
{
tx=g_lca(xy2,x1);
if(tx==xy2)
{
y1=g_lca(x1,x2);
tx=g_lca(x1,y2);
if(dep[tx]>dep[y1]) y1=tx;
xy1=x1=xy2;
return ;
}
tx=g_lca(xy2,y1);
if(tx==xy2)
{
xy1=x1=xy2;
tx=g_lca(y1,y2);
y1=g_lca(y1,x2);
if(dep[tx]>dep[y1]) y1=tx;
return ;
}
}
x1=-1; return ;
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<n;i++)
{
int x,y,c; scanf("%d%d%d",&x,&y,&c);
ins(x,y,c); ins(y,x,c);
}
dfs(1);
for(int i=1;i<maxl;i++)
for(int j=1;j<=n;j++)
{
int df=fa[j][i-1];
fa[j][i]=fa[df][i-1];
if(fs[j][i-1]<fs[df][i-1])
fs[j][i]=fs[df][i-1];
else fs[j][i]=fs[j][i-1];
}
for(int i=1;i<=m;i++)
{
int x,y; scanf("%d%d",&x,&y);
q[i].x=x; q[i].y=y; q[i].Lca=g_lca(x,y);
q[i].c=dis[q[i].x]+dis[y]-2*dis[q[i].Lca];
if(q[i].Lca==y) swap(q[i].x,q[i].y);
}
sort(q+1,q+m+1,cmp);
int ans=0,tx=0;
up(tx,gmx(q[m].Lca,q[m].x));
up(tx,gmx(q[m].Lca,q[m].y));
ans=max( q[m].c-tx,q[m-1].c );
int x=q[m].x,y=q[m].y,xy=q[m].Lca;
for(int i=m-1;i>=1;i--)
{
int t1=q[i-1].c;
solve(x,y,xy,q[i].x,q[i].y,q[i].Lca);
if(x==-1||x==y) break;
int t2=0;
up(t2,gmx(xy,x));
up(t2,gmx(xy,y));
up(t1,q[m].c-t2);
if(ans>t1) ans=t1;
}
printf("%d\n",ans);
return 0;
}