BZOJ3727: PA2014 Final Zadanie
乱搞
题解:
感谢fqk dalao
画柿子!
令点
1
为根,设
b[i]=b[fai]−size[i]+(size[1]−size[i])(i>1)
a[i]=size[i]−∑size[soni]
根据以上式子,我们有了 size[i](i>1) 和 size[1] 的关系,和 a[i] 和 size[i] 的关系,所以就可以得到 a[i] 和 size[1] 的关系,又因为 b[1]=∑a[i]×dis[i] ,所以可以得到 b[1] 和 size[1] 的关系,就得到了 size[1] ,然后就能求出所有的 a[i] 了。
Code:
#include <iostream>
#include <cstring>
#include <cstdio>
#define D(x) cout<<#x<<" = "<<x<<" "
#define E cout<<endl
using namespace std;
const int N = 300005;
int n,dis[N],b[N];
struct Edge{
int to, next;
} e[N*2];
int head[N], ec;
void add(int a, int b){
ec++; e[ec].to=b; e[ec].next=head[a]; head[a]=ec;
}
struct Data{
double k,b;
Data (double _k=0, double _b=0) { k=_k; b=_b; }
Data operator + (Data x) { return Data(k+x.k, b+x.b); }
Data operator - (Data x) { return Data(k-x.k, b-x.b); }
Data operator * (double x) { return Data(k*x, b*x); }
} a[N], size[N];
double ans[N],size1;
void dfs(int u, int f){
size[u]=Data(0.5,(b[f]-b[u])*0.5);
a[u]=size[u];
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(v==f) continue;
dis[v]=dis[u]+1;
dfs(v,u);
a[u]=a[u]-size[v];
}
}
int main(){
freopen("a.in","r",stdin);
scanf("%d",&n);
int u,v;
for(int i=1;i<n;i++){
scanf("%d%d",&u,&v);
add(u,v); add(v,u);
}
for(int i=1;i<=n;i++) scanf("%d",&b[i]);
dfs(1,0);
Data tp;
for(int i=2;i<=n;i++) tp=tp+(a[i]*(double)dis[i]);
ans[1]=size1=((double)(b[1]-tp.b))/tp.k;
for(int i=2;i<=n;i++){
ans[i]=a[i].k*size1+a[i].b;
ans[1]-=ans[i];
}
for(int i=1;i<=n;i++) printf("%lld%c",(long long)ans[i],i==n?'\n':' ');
}