Ah good to bother with this problem ....
Basic ideas are available online.
One thing to note is that if the source of the army is not matched at the time of the match, then the source is matched first. (for no cost).
But the data good water ....
#include <iostream>#include<cstdio>#include<cstring>#include<algorithm>#defineMAXV 50050#defineMaxe 100500using namespacestd;intN,x,y,z,g[maxv],nume=0, m,c[maxv],anc[maxv][ -],dis[maxv][ -],l=1, r=0, disr[maxv],kr=0, FATH[MAXV];inttop=0, cnt=0;BOOLVIS[MAXV],RET[MAXV];structedge{intV,W,NXT;} E[maxe];structstatus{intVal,id;} REGIS[MAXV],STACK[MAXV];BOOLcmp (status A,status b) {returna.val<B.val;}voidAddedge (intUintVintW) {e[++nume].v=v; E[NUME].W=W; E[NUME].NXT=G[u]; G[u]=Nume;}voidDFS1 (intXintfather) { if(father==1) fath[x]=x; Else if(x!=1) fath[x]=Fath[father]; for(intI=g[x];i;i=e[i].nxt) { intv=e[i].v; if(v!=father) {anc[v][0]=x;dis[v][0]=E[I].W; DISR[V]=disr[x]+e[i].w;r=Max (R,disr[v]); DFS1 (V,X); } }}BOOLDFS2 (intXintfather) { if(Vis[x])return true; intcnt1=0, cnt2=0; for(intI=g[x];i;i=e[i].nxt) { intv=e[i].v; if(v!=father) {Cnt1++; if(DFS2 (v,x)) cnt2++; } } if((Cnt1==cnt2) && (cnt1!=0))return true; return false;}voidget_table () {R+=KR; for(intI=1; i<= -; i++) for(intj=1; j<=n;j++) {Anc[j][i]=anc[anc[j][i-1]][i-1]; Dis[j][i]=dis[j][i-1]+dis[anc[j][i-1]][i-1]; }}intGET_PNT (intXintR) { for(intI= -; i>=0; i--) { if(r>=Dis[x][i]) {R-=Dis[x][i]; X=Anc[x][i]; } } returnx;}BOOLCheckintx) {memset (Vis,false,sizeof(VIS)); memset (ret,false,sizeof(ret)); Top=0; cnt=0; for(intI=1; i<=m;i++) { intv=C[i]; if(disr[v]<x) {top++; Stack[top].val=x-Disr[v]; Stack[top].id=Fath[v]; } Else if(disr[v]==x) vis[fath[v]]=true; ElseVIS[GET_PNT (v,x)]=true; } for(inti=g[1];i;i=e[i].nxt) { intv=e[i].v; if(!DFS2 (V,1) ) {regis[++cnt].val=Disr[v]; Regis[cnt].id=v; RET[V]=true; } } if(top<cnt)return false; Sort (Stack+1, stack+top+1, CMP); Sort (Regis+1, regis+cnt+1, CMP); intp1=1, p2=1; while((p2<=cnt) && (p1<=top)) { if(Ret[stack[p1].id]) {ret[stack[p1].id]=false;p 1++;} Else { while((!ret[regis[p2].id]) && (p2<=cnt)) p2++; while((Stack[p1].val<regis[p2].val) && (p1<=top)) p1++; if(p2==cnt+1) Break; if(p1==top+1) Break; Ret[regis[p2].id]=false;p 1++;p 2++; } } for(inti=g[1];i;i=e[i].nxt) { intv=e[i].v; if(Ret[v])return false; } return true;}intGet_ans () {intans; while(l<=r) {intMid= (l+r) >>1; if(Check (mid)) {ans=mid;r=mid-1;} ElseL=mid+1; } returnans;}intMain () {scanf ("%d",&N); for(intI=1; i<=n-1; i++) {scanf ("%d%d%d",&x,&y,&z); Addedge (x, y, z); Addedge (Y,X,Z); if((x==1) || (y==1)) kr=Max (kr,z); } scanf ("%d",&m); for(intI=1; i<=m;i++) scanf ("%d",&C[i]); DFS1 (1,0); Get_table (); printf ("%d\n", Get_ans ()); return 0;}
Codevs 1218 Outbreak control