Time limit per test: 1.0 seconds
Memory limit: 256 megabytes
星光镇的地图是有 n 个点, n−1 条路,这些点从 1 到 n 编号,两两之间都可达;这 n−1 条路的长度都是 1 。
这 n 个点是居民聚居点,第 i 个点上有 ai 个居民。去年的时候,星光镇政府曾经做了个人口普查,他们投入了大量的资金,获知了所有节点的 ai ,而获知的目的,就是为新政府大楼的选址做准备的。由于新政府大楼一定会建在一个居民聚居点上,所以星光镇政府求出了对于每个聚居点 j 的「政府大楼收益评估函数」:
其中 dis(i,j) 是 i,j 号点之间的最短距离。特别的, dis(i,i)=0 。
新政府大楼造好了,政府自然而然地进行了一些证据销毁工作,同时「一不小心」销毁了重金得来的人口普查数据:也就是说 ai 都丢失了。但是巧的是,所有的收益评估函数值 p1,p2,…,pn 竟然都留存了下来。星光镇数据研究所唐纳德博士表示:「从这些函数值中,我们完全可以将所有的人口数据都反求出来。」但是唐纳德博士,虽然是一个著名的数学天才,但却很有可能是一个假博士,他这话自然不能当真。所以当星光镇政府又要造一个新的政府大楼,又要用到这些人口数据时,他们花费了巨资进行再调查。
身在异国的你听到此事后大笑不止,利用 p1,p2,…,pn 轻轻松松地求出了 a1,a2,a3,…,an 。
Input
输入具有如下形式:
nu1 v1⋮un−1 vn−1p1 p2 … pn−1 pn
第一行一个整数 n 。
接下来 n−1 行,每行两个整数 ui,vi ( 1≤ui,vi≤n ),分别表示这 n−1 条路。这 n−1 条路都可以双向通行。两个居民聚居点之间不会有多条路相连,也不会有一条路的两端连接了同一个居民聚居点。
最后一行,用空格隔开的 n 个整数 p1,p2,…,pn ,表示收益评估函数。
数据保证答案有解,并且满足 0≤a1,a2,…,an≤1 000 。
数据规模约定:
- 对于 Easy 档: 1≤n≤100 。
- 对于 Hard 档: 1≤n≤250 000 。
Output
依次序输出 a1,a2,…,an 。如果有多解,输出任意解。
Examples
2 1 2 11 9
9 11
6 1 2 1 3 3 4 3 5 5 6 32 45 19 28 16 21
0 1 2 3 4 5
因为easy题数据小,可以解方程做。
高斯消元模板拉kuangbin。
注意精度,卡了一万次。
(但我觉得解法肯定不是这样做的,但我菜啊
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
#define LL long long
#define eps 1e-8
const int maxn=1000;
double a[maxn][maxn],x[maxn];//方程的左边的矩阵和等式右边的值,求解之后x存的就是结果
int equ,var;//方程数和未知数个数
int Gauss()
{
int i,j,k,col,max_r;
for(k=0,col=0;k<equ&&col<var;k++,col++) {
max_r=k;
for(i=k+1;i<equ;i++)
if(fabs(a[i][col])>fabs(a[max_r][col]))
max_r=i;
if(fabs(a[max_r][col])<eps)
return 0;
if(k!=max_r) {
for(j=col;j<var;j++)
swap(a[k][j],a[max_r][j]);
swap(x[k],x[max_r]);
}
x[k]/=a[k][col];
for(j=col+1;j<var;j++)
a[k][j]/=a[k][col];
a[k][col]=1;
for(i=0;i<equ;i++)
if(i!=k) {
x[i]-=x[k]*a[i][k];
for(j=col+1;j<var;j++)
a[i][j]-=a[k][j]*a[i][col];
a[i][col]=0;
}
}
return 1;
}
int head[maxn],nxt[maxn],sz=0,to[maxn];
void add(int u,int v)
{
nxt[sz]=head[u];
to[sz]=v;
head[u]=sz++;
}
void dfs(int u,int pre,double now,int x)
{
a[x][u]=now;
for(int i=head[u];~i;i=nxt[i]){
int v=to[i];
if(v==pre) continue;
dfs(v,u,now+1,x);
}
}
int main()
{
for(int i=0;i<=111;i++) head[i]=-1;
memset(a,0,sizeof a);
memset(x,0,sizeof x);
sz=0;
int n;
scanf("%d",&n);
for(int i=1;i<n;i++){
int u,v;
scanf("%d %d",&u,&v);
u--;
v--;
add(u,v);
add(v,u);
}
for(int i=0;i<n;i++){
double p;scanf("%lf",&p);
x[i]=p;
}
for(int i=0;i<n;i++){
dfs(i,-1,0,i);
}
equ=n;
var=n;
Gauss();
for(int i=0;i<n;i++){
for(int k=0;k<=1000;k++){
if(fabs(x[i]-k)<eps){
printf("%d%c",k,i==n-1?'\n':' ');
}
}
}
}