Title: https://www.lydsy.com/JudgeOnline/problem.php?id=2238
For a long day ...
First, you want to know the smallest of the substitutions after each edge is removed;
Conversely, each edge that is not on the MST, if joined, will have an effect on a path, specifically, that is, all the edges on this path can be replaced with this non-MST edge after being deleted.
So you can use the tree to profile, for each non-MST edge, maintain the minimum value on the path;
So wrote a bit, but WA, take a closer look, MN and Lzy update of the place seems a bit less right, such as no update MN can also update Lzy what ... (as MN is also updated by the son, it may be smaller than lzy ...)
Anyway is to take min, Mark permanent is very convenient (simply did not Lzy), and then with Narh learned a bit of MN mark permanent of the wording.
The code is as follows:
#include <iostream>#include<cstdio>#include<cstring>#include<algorithm>#defineMid ((l+r) >>1)#defineLS (x<<1)#defineRS (x<<1|1)using namespacestd;int Constxn=50005, xm=1e5+5, inf=0x3f3f3f3f;intn,m,hd[xn],ct,nxt[xn<<1],to[xn<<1],dep[xn],siz[xn],son[xn],dfn[xn],top[xn],fa[xn],tim;intmn[xn<<2],lzy[xn<<2],ans;BOOLUSE[XM],FL;structn{intU,v,w,id;} E[XM];intRd () {intret=0, f=1;CharCh=GetChar (); while(ch<'0'|| Ch>'9'){if(ch=='-') f=0; Ch=GetChar ();} while(ch>='0'&&ch<='9') ret= (ret<<3) + (ret<<1) +ch-'0', ch=GetChar (); returnf?ret:-ret;}voidAddintXintY) {to[++ct]=y; nxt[ct]=hd[x]; hd[x]=CT;}BOOLCMP (N x,n y) {returnx.w<Y.W;}BOOLCMP2 (N x,n y) {returnx.id<y.id;}intFindintx) {returnfa[x]==x?x:fa[x]=find (Fa[x]);}voidDfsintx) {Dep[x]=dep[fa[x]]+1; siz[x]=1; for(intI=hd[x],u;i;i=Nxt[i]) { if((U=to[i]) ==fa[x])Continue; Fa[u]=x; DFS (U); siz[x]+=Siz[u]; if(Siz[u]>siz[son[x]]) son[x]=u; }}voidDFS2 (intx) {Dfn[x]=++Tim; if(Son[x]) top[son[x]]=TOP[X],DFS2 (son[x]); for(intI=hd[x],u;i;i=Nxt[i]) { if((U=to[i]) ==fa[x]| | U==SON[X])Continue; Top[u]=u; DFS2 (u); }}voidPushdown (intx) { if(lzy[x]==-1)return; if(Lzy[x]<mn[ls]) mn[ls]=lzy[x],lzy[ls]=Lzy[x]; if(Lzy[x]<mn[rs]) mn[rs]=lzy[x],lzy[rs]=Lzy[x]; LZY[X]=-1;}voidUpdateintXintLintRintLintRintd) { //if (l>=l&&r<=r) {if (d<mn[x]) mn[x]=d,lzy[x]=d; return;} //pushdown (x); if(L>=L&&R<=R) {mn[x]=min (mn[x],d);return;} //mn[x]=min (mn[x],d); if(mid>=L) Update (LS,L,MID,L,R,D); if(mid<r) Update (rs,mid+1, r,l,r,d); //mn[x]=min (Mn[ls],mn[rs]);}voidChangeintXintYintd) { while(top[x]!=Top[y]) { if(dep[top[x]]<Dep[top[y]]) swap (x, y); Update (1,1, n,dfn[top[x]],dfn[x],d); X=Fa[top[x]]; } if(x==y)return; if(dep[x]<Dep[y]) swap (x, y); Update (1,1, n,dfn[y]+1, dfn[x],d);}intQueryintXintLintRintPOS) { if(L==R)returnMn[x]; //pushdown (x); //if (pos<=mid) return query (Ls,l,mid,pos); //else return query (rs,mid+1,r,pos); if(Pos<=mid)returnmin (mn[x],query (ls,l,mid,pos)); Else returnMin (Mn[x],query (rs,mid+1, R,pos));}intMain () {n=rd (); m=Rd (); for(intI=1, x,y,z;i<=m;i++) E[i].u=rd (), E[i].v=rd (), E[i].w=rd (), e[i].id=i; Sort (e+1, e+m+1, CMP); for(intI=1; i<=n;i++) fa[i]=i;intCnt=0; for(intI=1; i<=m;i++) { intX=find (e[i].u), y=find (E[I].V); if(x==y)Continue; Add (E[I].U,E[I].V); Add (E[I].V,E[I].U); Ans+=E[I].W; FA[X]=y; cnt++; use[e[i].id]=1;//ID if(cnt==n-1) Break; } if(cnt<n-1) fl=1; if(!FL)//Time Saving{fa[1]=0; Dfs1); top[1]=1; DFS2 (1); Memset (MN,0x3f,sizeofMN); memset (lzy,-1,sizeofLzy); Sort (e+1, e+m+1, CMP2); for(intI=1; i<=m;i++) { if(Use[i])Continue; Change (E[I].U,E[I].V,E[I].W); } } intq=Rd (); for(intI=1, x;i<=q;i++) {x=Rd (); if(FL) {Puts ("Not connected");Continue;} if(!use[x]) {printf ("%d\n", ans);Continue;} intK=query (1,1, N,max (DFN[E[X].U],DFN[E[X].V])); if(K==inf) puts ("Not connected"); Elseprintf"%d\n", ans-e[x].w+k); } return 0;}
Bzoj 2238 mst--Tree cut +mn marker Permanent