洛谷2680 运输计划(树上差分)
传送门
【题目分析】
tnnd。。。。。竟然卡树剖?95pts在逗我?
试了各种卡常均gg。。。。。
所以我先贴95pts树剖,tarjan什么的等我心情好了再补。。。。mmp
【代码~(不要吐槽写得丑)】
#include<bits/stdc++.h>
using namespace std;
const int MAXN=3e5+10;
const int MAXM=6e5+10;
int n,m,cnt,pts;
int s[MAXN],t[MAXN],lc[MAXN],len[MAXN],deep[MAXN];
const int RLEN=1<<18|1;
char nc() {
static char ibuf[RLEN],*ib,*ob;
(ib==ob) && (ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ib==ob) ? -1 : *ib++;
}
int Read() {
char ch=nc(); int i=0,f=1;
while(!isdigit(ch)) {if(ch=='-') f=-1; ch=nc();}
while(isdigit(ch)) {i=(i<<1)+(i<<3)+ch-'0'; ch=nc();}
return i*f;
}
void swap(int &x,int &y){
int t=x;
x=y,y=t;
}
namespace SLPF{
int head[MAXN],depth[MAXN],siz[MAXN],fa[MAXN],son[MAXN],top[MAXN];
int nxt[MAXM],to[MAXM],w[MAXM];
int dfn[MAXN],tot;
int a[MAXN],delta[MAXN];
void init(){
memset(head,-1,sizeof(head[0])*(pts+5));
}
void add(int x,int y,int z){
nxt[cnt]=head[x];
head[x]=cnt;
to[cnt]=y;
w[cnt]=z;
cnt++;
}
void dfs1(int u,int f){
siz[u]=1;
for(register int i=head[u];i!=-1;i=nxt[i]){
int v=to[i];
if(v==f)
continue;
a[v]=w[i];
depth[v]=depth[u]+1;
deep[v]=deep[u]+w[i];
fa[v]=u;
dfs1(v,u);
siz[v]+=siz[u];
if(siz[v]>siz[son[u]])
son[u]=v;
}
}
void dfs2(int u,int tp){
top[u]=tp;
dfn[u]=++tot;
if(!son[u])
return ;
dfs2(son[u],tp);
for(register int i=head[u];i!=-1;i=nxt[i]){
int v=to[i];
if(v==fa[u]||v==son[u])
continue;
dfs2(v,v);
}
}
int lca(int x,int y){
while(top[x]!=top[y]){
if(depth[top[x]]<depth[top[y]])
swap(x,y);
x=fa[top[x]];
}
return depth[x]<depth[y]?x:y;
}
void dfss(int u,int f){
for(register int i=head[u];i!=-1;i=nxt[i]){
int v=to[i];
if(v==f)
continue;
dfss(v,u);
delta[u]+=delta[v];
}
}
bool check(int x){
int sum=0,ss=0;
memset(delta,0,sizeof(delta[0])*(pts+5));
for(register int i=1;i<=m;++i){
if(len[i]>x){
sum++;
ss=max(ss,len[i]-x);
delta[s[i]]++;
delta[t[i]]++;
delta[lc[i]]-=2;
}
}
dfss(1,-1);
for(register int i=1;i<=n;++i){
if(delta[i]==sum&&a[i]>=ss)
return 1;
}
return 0;
}
}
int main(){
int l=0,r=5e7+7;
n=Read(),m=Read();
pts=n+2;
SLPF::init();
int x,y,z;
for(int i=1;i<n;++i){
x=Read(),y=Read(),z=Read();
SLPF::add(x,y,z),SLPF::add(y,x,z);
}
SLPF::dfs1(1,-1);
SLPF::dfs2(1,1);
for(register int i=1;i<=m;++i)
s[i]=Read(),t[i]=Read(),lc[i]=SLPF::lca(s[i],t[i]),len[i]=deep[s[i]]+deep[t[i]]-deep[lc[i]]*2,r=max(r,len[i]);;
int mid;
while(l<=r){
mid=l+r>>1;
if(SLPF::check(mid))
r=mid-1;
else
l=mid+1;
}
cout<<l;
return 0;
}