See the meaning of problems to minimize the longest path, apparently dichotomous answers, enumeration chain length does not exceed $ \ text {mid} $, and then try to test. `` `` `
Check whether there is a rear side is set to 0, all the chain length of $ \ le \ text {mid} $, whose ultimate goal is to let all $> \ text {mid} $ by finding a chain length of 0 subtracting the whole common side portion becomes $ \ le \ text {mid} $ a .
Then, the statistics of this $ TOT $ article exceeds $ \ text {mid} edge covering on the path of the chain $ a, a is covered edge $ TOT $ times may have the condition, so greedy find greatest satisfaction condition edge , to see whether all the chains (i.e. longest chain) into an $ \ le \ text {mid} $ a, $ O (n) $ differential tree can.
Thus $ O (n \ text {log} len) $.
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #define dbg(x) cerr << #x << " = " << x <<endl 7 using namespace std; 8 typedef long long ll; 9 typedef double db; 10 typedef pair<int,int> pii; 11 template<typename T>inline T _min(T A,T B){return A<B?A:B;} 12 template<typename T>inline T _max(T A,T B){return A>B?A:B;} 13 template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,1):0;} 14 template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,1):0;} 15 template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;} 16 template<typename T>inline T read(T&x){ 17 x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1; 18 while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x; 19 } 20 const int N=3e5+7; 21 struct thxorz{int to,nxt,w;}G[N<<1]; 22 struct stothx{int to,nxt,id;}Q[N<<1]; 23 struct query{int x,y,lca,dis;}q[N]; 24 int Head[N],tot=1,qh[N],qt; 25 int n,m,L,R,maxdis,maxe; 26 inline void Addedge(int x,int y,int z){ 27 G[++tot].to=y,G[tot].nxt=Head[x],Head[x]=tot,G[tot].w=z; 28 G[++tot].to=x,G[tot].nxt=Head[y],Head[y]=tot,G[tot].w=z; 29 } 30 inline void AddQuery(int x,int y,int id){ 31 Q[++qt].to=y,Q[qt].nxt=qh[x],qh[x]=qt,Q[qt].id=id; 32 Q[++qt].to=x,Q[qt].nxt=qh[y],qh[y]=qt,Q[qt].id=id; 33 } 34 #define y G[j].to 35 #define qy Q[j].to 36 int vis[N],anc[N],dep[N]; 37 int get_anc(int x){return x==anc[x]?x:anc[x]=get_anc(anc[x]);} 38 void tarjan(int x,int fa){ 39 anc[x]=x; 40 for(register int j=Head[x];j;j=G[j].nxt)if(y^fa)dep[y]=dep[x]+G[j].w,tarjan(y,x),anc[y]=x; 41 vis[x]=1; 42 for(register int j=qh[x];j;j=Q[j].nxt)if(vis[qy]) 43 q[Q[j].id].lca=get_anc(qy),q[Q[j].id].dis=dep[x]+dep[qy]-(dep[q[Q[j].id].lca]<<1),MAX(R,q[Q[j].id].dis); 44 } 45 int d[N],del,cnt; 46 int dfs(int x,int c){ 47 int ret=d[x]; 48 for(register int j=Head[x];j;j=G[j].nxt)if(y^G[c^1].to)ret+=dfs(y,j); 49 if(ret==cnt)MAX(del,G[c].w); 50 return ret; 51 } 52 #undef y 53 #undef qy 54 inline int check(int mid){ 55 memset(d,0,sizeof d),del=cnt=0; 56 for(register int i=1;i<=m;++i)if(q[i].dis>mid)++d[q[i].x],++d[q[i].y],d[q[i].lca]-=2,++cnt; 57 dfs(1,0); 58 return maxdis-del<=mid; 59 } 60 int main(){//freopen("test.in","r",stdin);freopen("test.ans","w",stdout); 61 read(n),read(m); 62 for(register int i=1,x,y,z;i<n;++i)read(x),read(y),read(z),Addedge(x,y,z),MAX(L,z); 63 for(register int i=1;i<=m;++i)read(q[i].x),read(q[i].y),AddQuery(q[i].x,q[i].y,i); 64 tarjan(1,0);maxdis=R,maxe=L;L=R-L;//dbg(maxdis),dbg(maxe); 65 while(L<R){ 66 int mid=L+R>>1; 67 if(check(mid))R=mid; 68 else L=mid+1; 69 } 70 printf("%d\n",L); 71 return 0; 72 }
Summary reflection: the bottleneck in check. The key is to look at all, do not all on maxdis; demand side covered several statistical difference may want to go on the tree.