Topic: Chinese
Title Link: Find Your Own
Dichotomous answer, then the edge larger than the answer needs to be modified one side, so all chains larger than the answer are marked (edge difference), assuming that such a chain has x, the maximum value of the record chain is k, the bipartite answer is mid, enumerate the edge, if K-edge weight <=mid, and this edge is covered by X times, indicating that the dichotomy answer is feasible, consider reducing the answer.
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=3e5+7; struct Edge{ int v,w,next; }edge[maxn<<1]; int head[maxn],top; void init(){ top=0; memset(head,-1,sizeof(head)); } void add(int u,int v,int w){ edge[top].v=v; edge[top].w=w; edge[top].next=head[u]; head[u]=top++; } int siz[maxn]; queue<int> q; int dep[maxn]; int fa[maxn][26]; const int ci=20; int dis[maxn]; void bfs(int st){ q.push(st); dep[st]=1; dis[st]=0; int u,v,w; while(!q.empty()){ u=q.front(); q.pop(); for(int i=head[u];i!=-1;i=edge[i].next){ v=edge[i].v; w=edge[i].w; if(dep[v]) continue; dep[v]=dep[u]+1; dis[v]=dis[u]+w; fa[v][0]=u; q.push(v); for(int j=1;j<=ci;++j) fa[v][j]=fa[fa[v][j-1]][j-1]; } } } int W[maxn];//The length of the edge between node u and father; bool vis[maxn]; void dfs(int u){ //vis[u]=1; int v; int maxx=-1; for(int i=head[u];i!=-1;i=edge[i].next){ v=edge[i].v; if(dep[v]<dep[u]) continue; W[v]=edge[i].w; dfs(v); siz[u]+=siz[v]; } } int lca(int x,int y){ if(dep[x]<dep[y]) swap(x,y); for(int i=ci;i>=0;--i) if(dep[fa[x][i]]>=dep[y]) x=fa[x][i]; if(x==y) return x; for(int i=ci;i>=0;--i) if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i]; return fa[x][0]; } int maxx; struct Ope{ int u,v,lcax,dis; }ope[maxn]; int m,n; bool check(int mid){ memset(siz,0,sizeof(siz)); //memset(vis,0,sizeof(vis)); int cnt=0; for(int i=1;i<=m;++i) if(ope[i].dis>mid){ ++cnt; ++siz[ope[i].u],++siz[ope[i].v],siz[ope[i].lcax]-=2; } if(!cnt) return 1; dfs(1); for(int i=2;i<=n;++i) if(maxx-W[i]<=mid&&siz[i]==cnt) return 1; return 0; } int main(){ int u,v,w,x; scanf("%d%d",&n,&m); init(); for(int i=1;i<n;++i){ scanf("%d%d%d",&u,&v,&w); add(u,v,w); add(v,u,w); } bfs(1); for(int i=1;i<=m;++i){ scanf("%d%d",&u,&v); x=lca(u,v); ope[i].u=u,ope[i].v=v,ope[i].lcax=x,ope[i].dis=dis[u]+dis[v]-2*dis[x]; maxx=max(maxx,ope[i].dis); } int l=0,r=3e8,mid; while(l<=r){ mid=(l+r)>>1; if(check(mid)) r=mid-1; else l=mid+1; } //cout<<l<<" "<<r<<endl; printf("%d\n",l); return 0; }