运输计划
最小化最大值问题,考虑用二分答案
check中一般用贪心策略
将每条路径的长度预处理,对二分的ans,将长度比ans大的取出来
并找出这些路径是否有一条重边使得最长的路径减了这条边后小于ans
注意dfs中参数少一点会更快,将dfs中访问顺序存到数组中,在每次check时不要再次dfs
数组要开大一点。。
#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define SZ(x) ((int)x.size())
#define ALL(x) x.begin(),x.end()
#define U(i,u) for(register ll i=head[u];i;i=nxt[i])
#define rep(i,a,b) for(register ll i=(a);i<=(b);++i)
#define per(i,a,b) for(register ll i=(a);i>=(b);--i)
using namespace std;
typedef long double ld;
typedef long long ll;
typedef unsigned int ui;
typedef pair<int,int> PII;
typedef vector<int> VI;
template<class T> inline void read(T &x){
x=0;char c=getchar();ll f=1;
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=x*10+c-'0';c=getchar();}x*=f;
}
template<class T> inline void cmin(T &x, T y){x=x<y?x:y;}
template<class T> inline void cmax(T &x, T y){x=x>y?x:y;}
const int N=1000100;
ll n,m,head[N],nxt[N],v[N],cnt,uu[N],vi[N],li[N],anc[N][24];
ll w[N],su,mx,mxx,mi=9999999999,s[N],dep[N];
ll num[N],ct;
ll vis[N],tmp;
inline void add(ll x,ll y,ll z){nxt[++cnt]=head[x];head[x]=cnt;v[cnt]=y;w[cnt]=z;}
inline void dfs(ll now,ll d){
vis[now]=1;num[++ct]=now;dep[now]=d;U(i,now){
if(vis[v[i]])continue;s[v[i]]=s[now]+w[i];anc[v[i]][0]=now;dfs(v[i],d+1);
}
}
inline void init(){
memset(vis,0,sizeof(vis));dfs(1,0);
rep(j,1,23)rep(i,2,n){anc[i][j]=anc[anc[i][j-1]][j-1];}
}
inline void swim(ll &x,ll h){
for(ll i=0;h;i++){
if(h&1)x=anc[x][i];
h>>=1;
}
}
inline ll lca(ll x,ll y){
if(dep[x]<dep[y])swap(x,y);
if(y==1)return 1;
swim(x,dep[x]-dep[y]);
if(x==y)return x;
for(ll i=23;i>=0;i--){
if(anc[x][i]^anc[y][i]){
x=anc[x][i];y=anc[y][i];
}
}
return anc[x][0];
}
inline bool check(ll an){
memset(vis,0,sizeof(vis));
tmp=0;rep(i,1,m){
if(dep[i]>an){
++vis[uu[i]],++vis[vi[i]],vis[li[i]]-=2;
++tmp;
}
}
if(!tmp)return 1;
per(i,n,2)vis[anc[num[i]][0]]+=vis[num[i]];
rep(i,1,n)if(vis[i]>=tmp&&mx-(s[i]-s[anc[i][0]])<=an)return 1;
return 0;
}
int main(){
read(n);read(m);ll a,b;ll c;rep(i,1,n-1){read(a);read(b);read(c);add(a,b,c);add(b,a,c);su+=c;cmax(mxx,c);}
init();rep(i,1,m){read(uu[i]);read(vi[i]);li[i]=lca(uu[i],vi[i]);}
rep(i,1,m){dep[i]=s[vi[i]]+s[uu[i]]-2*s[li[i]];cmax(mx,dep[i]);cmin(mi,dep[i]);}
ll l=0,r=su,mid;
while(r-l>=3){
mid=(r+l)>>1;if(check(mid))r=mid;else l=mid+1;
}
for(ll i=l;i<=r;i++){
if(check(i)){
printf("%lld
",i);
return 0;
}
}
return 0;
}
/*
6 3
1 2 3
1 6 4
3 1 7
4 3 12
3 5 5
3 6
2 5
4 5
*/