G.树上求和

G.树上求和

题意:
给你一棵n个顶点n-1条边的树,让你给n-1条边分别赋值1~n-1 ,每个数只能用一次,求整棵树最终任意两点之间的权值和。

题解:
我们只需要计算每条边被访问了多少次就行了,然后根据访问次数从小到大排序,最小的赋值最大的、…、最大的赋值最小的。

访问次数=该条边左边的端点数 * 该条边右边的端点数( size * (n-size) )

dfs找出每个顶点左边或者右边的个数,计算访问的次数,从小到大计算就ok了。

code:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
#include<vector>
#include<set>
#include<sstream>
using namespace std;
typedef long long ll;
const ll maxn=1e6+10;
const ll inf=0x3f3f3f3f3f3f3f3f;
void io(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);}
ll he[maxn],ver[maxn],ne[maxn],vis[maxn];
ll size[maxn],ans[maxn];
ll cnt=0;
void add(ll x,ll y)
{
	ver[++cnt]=y;
	ne[cnt]=he[x];
	he[x]=cnt;	
} 
void dfs(ll u)
{
	size[u]=1;
	for(int i=he[u];i;i=ne[i])
	{
		ll num=ver[i];
		if(!vis[num])
		{
			vis[num]=1;
			dfs(num);
			size[u]+=size[num];
		}
	} 
}
int main()
{
	io();
	ll n;
	cin>>n;
	for(int i=1;i<n;i++)
	{
		ll x,y;
		cin>>x>>y;
		add(x,y);
		add(y,x);
	}
	vis[1]=1;
	dfs(1);
	for(int i=2;i<=n;i++)
		ans[i]=size[i]*(n-size[i]);
	sort(ans+2,ans+n+1);
	ll sum=0;
	for(int i=2;i<=n;i++)	
		sum+=ans[i]*(n-i+1);
	cout<<sum<<endl;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
List.stream分组求和是一种常见的数据处理操作,它可以将一个List中的元素照某个属性进行分组,并对每个分组中的元素进行求和操作。下面是一个示例代码: ```java import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { // 创建一个包含多个Person对象的List List<Person> personList = Arrays.asList( new Person("Alice", "A", 100), new Person("Bob", "A", 200), new Person("Charlie", "B", 300), new Person("David", "B", 400), new Person("Eve", "C", 500) ); // 使用stream进行分组求和 Map<String, Integer> sumByGroup = personList.stream() .collect(Collectors.groupingBy(Person::getGroup, Collectors.summingInt(Person::getScore))); // 输出结果 sumByGroup.forEach((group, sum) -> System.out.println(group + ": " + sum)); } } class Person { private String name; private String group; private int score; public Person(String name, String group, int score) { this.name = name; this.group = group; this.score = score; } public String getName() { return name; } public String getGroup() { return group; } public int getScore() { return score; } } ``` 上述代码中,我们创建了一个包含多个Person对象的List,并使用stream对其进行操作。通过`Collectors.groupingBy`方法,我们可以按照Person对象的group属性进行分组,然后使用`Collectors.summingInt`方法对每个分组中的score属性进行求和。最后,我们将结果存储在一个Map中,并输出每个分组的求和结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

aaHua_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值