Topic Link
Topic ideas
In fact, this idea that they have a problem, but in the end did not write the code but it is not to see a solution to a problem. This question and one question is actually very similar to race weeks are seeking contributions
This problem requires thinking in terms of contribution to count, for each edge of the contribution of the answer, which is equal to the left subtree node point number × the right subtree side length × number of nodes.
So we just from the first point DFS, the number of nodes pretreatment each subtree. Then traverse all sides.
The number left to the right subtree node × number of sub-tree nodes point product preserved. Descending order, from front to back and then again traversed respectively multiplied by 1/2/3 / ... / n-1, can be combined.
Time complexity of O (n × log (n)).
To find the nodes from around the size of the sort, because inside there are n total, but in fact only n-1 edges. There is a s [1] = 0, will certainly be discarded.
pass: two-way side do not open the screen twice to eat
Code
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
ll ans,s[maxn],pos[maxn];
int head[maxn],cnt,cnt2,n,u,v;
struct node{
int to,next;
}e[maxn<<1];//双向边
void add(int u,int v){
e[++cnt].to=v;
e[cnt].next=head[u];
head[u]=cnt;
}
void dfs(int son,int fa){
pos[son]=1;//左边有多少个节点
for(int i=head[son];i;i=e[i].next){
if(e[i].to!=fa){
dfs(e[i].to,son);
pos[son]=pos[son]+pos[e[i].to];
}
}
s[++cnt2]=pos[son]*(n-pos[son]);//左节点数量乘以右节点数量
}
bool cmp(ll a,ll b){
return a>b;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n-1;i++){
scanf("%d %d",&u,&v);
add(u,v),add(v,u);
}
dfs(1,0);
sort(s+1,s+1+cnt2,cmp);//要从大到小因为里面第一个元素为0
for(int i=1;i<=n-1;i++){
ans=ans+s[i]*i;
}
printf("%lld",ans);
return 0;
}