#include<cstdio>
#include<cmath>
#include<algorithm>
#include<vector>
#include<string>
#include<functional>
#include<ctype.h>
#include<map>
#define LL long long
#define LD long double
#define L(x) ((x).size())
#define FI first
#define SE second
#define MP make_pair
#define PB push_back
using namespace std;
int n,m,a,b;
LL certain,ncost;
vector<int> v[501000];
int cost[501000];
bool vis1[501000];
bool vis2[501000];
int parent[501000];
vector<int> children[501000];
int vel,START,END;
LL asum,mn,now,last;
vector<int> act;
void count_certain(int x);
void ukorzen(int x,int p);
void licz(int x);
pair<int,int> inv[501000];
int main(){
scanf("%d%d",&n,&m);
for(int i=0;i<n-1;++i){
scanf("%d%d",&a,&b);
v[a].PB(b);
v[b].PB(a);
}
for(int i=1;i<=m;++i)
scanf("%d",&cost[i]);
count_certain(1);
for(int i=m+1;i<=n;++i){
if(!vis2[i]){
ukorzen(i,0);
licz(i);
}
}
printf("%lld\n",certain+ncost);
}
void licz(int x){
if(x<=m){
inv[x] = MP(cost[x],cost[x]);
}
else{
for(int i=0;i<L(children[x]);++i)
licz(children[x][i]);
act.clear();
asum = 0;
for(int i=0;i<L(children[x]);++i){
act.PB(inv[children[x][i]].FI);
act.PB(inv[children[x][i]].SE);
asum+= inv[children[x][i]].FI;
}
vel = -L(children[x]);
sort(act.begin(),act.end());
last = 0;
mn = 1e9;mn*=mn;
for(int i=0;i<L(act);++i){
now = act[i];
asum+=(now-last)*vel;
if(asum<mn){
mn = asum;
START = now;
}
else if(asum==mn)
END = now;
++vel;
last=now;
}
ncost+= mn;
inv[x].FI = START;
inv[x].SE = END;
}
}
void ukorzen(int x,int p){
vis2[x] = true;
parent[x] = p;
children[p].PB(x);
if(x>m)
for(int i=0;i<L(v[x]);++i)
if(!vis2[v[x][i]])
ukorzen(v[x][i],x);
}
void count_certain(int x){
vis1[x] = true;
for(int i=0;i<L(v[x]);++i){
if(!vis1[v[x][i]]){
if(x<=m && v[x][i]<=m){
certain+=abs(cost[x]-cost[v[x][i]]);
}
count_certain(v[x][i]);
}
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | #include<cstdio> #include<cmath> #include<algorithm> #include<vector> #include<string> #include<functional> #include<ctype.h> #include<map> #define LL long long #define LD long double #define L(x) ((x).size()) #define FI first #define SE second #define MP make_pair #define PB push_back using namespace std; int n,m,a,b; LL certain,ncost; vector<int> v[501000]; int cost[501000]; bool vis1[501000]; bool vis2[501000]; int parent[501000]; vector<int> children[501000]; int vel,START,END; LL asum,mn,now,last; vector<int> act; void count_certain(int x); void ukorzen(int x,int p); void licz(int x); pair<int,int> inv[501000]; int main(){ scanf("%d%d",&n,&m); for(int i=0;i<n-1;++i){ scanf("%d%d",&a,&b); v[a].PB(b); v[b].PB(a); } for(int i=1;i<=m;++i) scanf("%d",&cost[i]); count_certain(1); for(int i=m+1;i<=n;++i){ if(!vis2[i]){ ukorzen(i,0); licz(i); } } printf("%lld\n",certain+ncost); } void licz(int x){ if(x<=m){ inv[x] = MP(cost[x],cost[x]); } else{ for(int i=0;i<L(children[x]);++i) licz(children[x][i]); act.clear(); asum = 0; for(int i=0;i<L(children[x]);++i){ act.PB(inv[children[x][i]].FI); act.PB(inv[children[x][i]].SE); asum+= inv[children[x][i]].FI; } vel = -L(children[x]); sort(act.begin(),act.end()); last = 0; mn = 1e9;mn*=mn; for(int i=0;i<L(act);++i){ now = act[i]; asum+=(now-last)*vel; if(asum<mn){ mn = asum; START = now; } else if(asum==mn) END = now; ++vel; last=now; } ncost+= mn; inv[x].FI = START; inv[x].SE = END; } } void ukorzen(int x,int p){ vis2[x] = true; parent[x] = p; children[p].PB(x); if(x>m) for(int i=0;i<L(v[x]);++i) if(!vis2[v[x][i]]) ukorzen(v[x][i],x); } void count_certain(int x){ vis1[x] = true; for(int i=0;i<L(v[x]);++i){ if(!vis1[v[x][i]]){ if(x<=m && v[x][i]<=m){ certain+=abs(cost[x]-cost[v[x][i]]); } count_certain(v[x][i]); } } } |
English