暴力分:
贪心20,不写了。
正解:二分
二分最短的时间。
通过预处理求出每条航线的总时间。
二分一个时间。
是否存在一条边,减下它的时间让所有的大于mid的路,全部小于mid。
如何找一条被重复经过的边?
树上差分。
对于数组v
V[起点,终点]+1,V[lca(起点,终点)]-=2
从i到他的父节点的路径被经过的次数即为i子树v的和。
注意要用Tarjan,不能用倍增(被卡了一个点)233
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxm=610000;
int head[2][maxm],to[2][2*maxm],cost[2][2*maxm],net[2][2*maxm],lca[2][2*maxm];
int fat[maxm],dis[maxm],cap[maxm];
int v[maxm];
bool vis[maxm];
int cnt[2];
int n,m;
struct node{
int s,t,dis;
}a[maxm];
void add(int id,int x,int y,int c)
{
cnt[id]++;
to[id][cnt[id]]=y;
cost[id][cnt[id]]=c;
net[id][cnt[id]]=head[id][x];
head[id][x]=cnt[id];
}
int find(int x)
{
if(fat[x]==x) return x;
else return fat[x]=find(fat[x]);
}
void tarjan(int x,int f,int Dis)
{
vis[x]=1;
dis[x]+=dis[f]+Dis;
fat[x]=x;
for(int i=head[0][x];i;i=net[0][i])
if(to[0][i]!=f)
{
tarjan(to[0][i],x,cost[0][i]);
fat[to[0][i]]=x;
cap[to[0][i]]=cost[0][i];
}
for(int i=head[1][x];i;i=net[1][i])
if(vis[to[1][i]])
{
lca[1][i]=find(to[1][i]);
if(i%2)
lca[1][i+1]=lca[1][i];
else
lca[1][i-1]=lca[1][i];
}
}
int dfs(int x,int fat)
{
for(int i=head[0][x];i;i=net[0][i])
if(to[0][i]!=fat)
dfs(to[0][i],x),v[x]+=v[to[0][i]];
return v[x];
}
bool check(int mid)
{
memset(v,0,sizeof(v));
int cnt=0,max_d=0;
for(int i=1;i<=m;i++)
if(a[i].dis>mid)
{
//printf("%d\n",a[i].dis);
v[a[i].s]+=1;
v[a[i].t]+=1;
v[lca[1][2*i]]-=2;
max_d=max(max_d,a[i].dis);
cnt++;
}
dfs(1,0);
/*printf("%d\n",cnt);
for(int i=1;i<=n;i++)
printf("%d ",v[i]);*/
for(int i=2;i<=n;i++)
if(v[i]==cnt&&max_d-cap[i]<=mid)
return 1;
//puts("");
return 0;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1,x,y,c;i<n;i++)
{
scanf("%d%d%d",&x,&y,&c);
add(0,x,y,c);
add(0,y,x,c);
}
for(int i=1,x,y;i<=m;i++)
{
scanf("%d%d",&x,&y);
a[i].s=x,a[i].t=y;
add(1,x,y,0);
add(1,y,x,0);
}
tarjan(1,0,0);
int r=0;
for(int i=1;i<=m;i++)
a[i].dis=(dis[a[i].s]+dis[a[i].t]-2*dis[lca[1][2*i]]),r=max(r,a[i].dis);
int l=0;
/*for(int i=1;i<=n;i++)
printf("%d ",cap[i]);*/
while(l<=r)
{
int mid=l+r>>1;
if(check(mid)) r=mid-1;
else l=mid+1;
}
printf("%d",l);
}