Analysis: The problem looks difficult at one glance, but does not work, we change the angle: Consider the contribution of each side
Because it is a tree, one side divides the tree into two sets, if there are X schools on the left and Y schools on the right.
Greedy to think, let each side in the school's path the most, so contribute to min (x, y)
Implementation: A DFS at a time, the complexity of O (N)
#include <stdio.h>#include<iostream>#include<algorithm>#include<string.h>#include<vector>#include<math.h>#include<stack>#include<map>using namespaceStd;typedefLong LongLL;Const intN = 2e5+5;Const intINF =0x3f3f3f3f;ConstLL mod = 1ll<< +;inthead[n],tot,sum[n],n,k;structedge{intV,next;} Edge[n<<1];voidAddintUintv) {EDGE[TOT].V=v; Edge[tot].next=Head[u]; Head[u]=tot++;} LL ans;voidDfsintUintf) { for(intI=head[u];~i;i=Edge[i].next) { intv=edge[i].v; if(v==f)Continue; DFS (V,U); Ans+=min (K-Sum[v],sum[v]); Sum[u]+=Sum[v]; }}intMain () {scanf ("%d%d", &n,&k); k<<=1; memset (Head,-1,sizeof(head)); for(intI=1; i<=k;++i) { intU;SCANF ("%d",&T); ++Sum[u]; } for(intI=1; i<n;++i) { intU,V;SCANF ("%d%d",&u,&v); Add (u,v); add (V,u); } DFS (1,0); printf ("%i64d\n", ans); return 0;}
View Code
Codeforces 700B connecting Universities greedy DFS