#include using namespace std; const int maxn=2e5+5; const int maxe=4e6+5; struct Edge { int v,w,nxt,pre; }edge[maxe],E[maxe];//原图,重构图 int Head[maxn],head[maxn],rear,tot,tail[maxn]; int mark[maxn],sz[maxn]; int N,n,cnt,root,midedge,Max; void init()//原图初始化 { memset(head,-1,sizeof(head)); tot=0; } void INIT()//重构图初始化 { memset(Head,-1,sizeof(Head)); rear=0;//下标从零开始 } void add(int u,int v,int w) { edge[tot].v=v; edge[tot].w=w; edge[tot].nxt=head[u]; head[u]=tot++; } void ADD(int u,int v,int w) { E[rear].v=v; E[rear].w=w; E[rear].nxt=Head[u]; Head[u]=rear++; } void Delete(int u,int i)//删除u结点的i号边 { if(Head[u]==i) Head[u]=E[i].nxt; else E[E[i].pre].nxt=E[i].nxt;//跳过该边 if(tail[u]==i)//指向u结点的最后一条边,相当于尾指针 tail[u]=E[i].pre; else E[E[i].nxt].pre=E[i].pre;//双向链表修改前驱 } //保证每个点的度不超过2 void build(int u,int fa) { int father=0; for (int i=head[u];~i;i=edge[i].nxt) { int v=edge[i].v,w=edge[i].w; if(v==fa)continue; if(father==0)//还没有增加子节点,直接连上 { ADD(u,v,w); ADD(v,u,w); father=u; } else//已经有一个子节点,则创建一个新节点,把v连在新节点上 { mark[++N]=0; ADD(N,father,0); ADD(father,N,0); father=N; ADD(v,father,w); ADD(father,v,w); } build(v,u); } } //nxt是下一条边的编号,pre是上一条边的编号 void get_pre()//得到每条边的前驱 { memset(tail,-1,sizeof(tail)); for(int i=1;i<=N;i++) { for(int j=Head[i];~j;j=E[j].nxt) { E[j].pre=tail[i]; tail[i]=j;//指向u结点的最后一条边,相当于尾指针 } } } void rebuild()//重构图 { INIT();//重构图初始化 N=n; for(int i=1;i<=N;i++) mark[i]=1; build(1,0); get_pre();//得到每条边的前驱 init();//原图初始化 } struct point { int u,dis; point() {} point(int _u,int _dis) { u=_u;dis=_dis; } bool operator<(const point& _A)const { return dis<_A.dis;//优先队列的优先级 } }; struct node { int rt,midlen,ans; //根节点,中心边的权值,答案(最长树链) int ls,rs; //左右子树编号 priority_queueq; }T[2*maxn];//注意:设为maxe会超时,节点个数为4N bool vis[maxn]; void dfs1(int u)//测试重建树结果 { vis[u]=1; for(int i=Head[u];~i;i=E[i].nxt) { int v=E[i].v,w=E[i].w; if(vis[v]) continue; cout<T[id].ans)//如果左儿子的结果大于根 T[id].ans=T[ls].ans; if(T[rs].ans>T[id].ans)//如果右儿子的结果大于根 T[id].ans=T[rs].ans; if(!T[ls].q.empty()&&!T[rs].q.empty())//穿过中心边的 T[id].ans=max(T[id].ans,T[ls].q.top().dis+T[rs].q.top().dis+T[id].midlen); } } void DFS(int id, int u) { root=id; Max=N; midedge=-1; T[id].rt=u; cout<<"root="<v int p2=E[midedge^1].v;//p2:u cout<<"中心边:"<