[codeforces 1363E] Tree Shuffling 可以回避排序的树上结构(链式结构不超时的写法)

Codeforces Round #646 (Div. 2)  参与排名人数14203

[codeforces 1363E]    Tree Shuffling   可以回避排序的树上结构(链式结构不超时的写法)

总目录详见https://blog.csdn.net/mrcrack/article/details/103564004

在线测评地址http://codeforces.com/contest/1363/problem/E

ProblemLangVerdictTimeMemory
E - Tree Shuffling GNU C++17Accepted342 ms17200 KB

思路:

数据传入,采用自顶向下的方式,数据处理,采用自底向上的方式。此种方式,在此题中,可避免单独写排序算法,可避免单独写更新算法,有效的避免了链式结构的超时,也是该题编写过程中的精妙之处。

看懂该题代码,需要具备的知识是,熟练掌握子树节点数量计算对应的算法。

AC代码如下

#include <cstdio>
#include <algorithm>
#define maxn 200010
#define LL long long
#define INF 1000000010
using namespace std;
int a[maxn],b[maxn],c[maxn],f[maxn],g[maxn],head[maxn],tot,n;
LL ans;
struct node{
	int to,next;
}e[maxn<<1];
void add_edge(int u,int v){//邻接表
	tot++,e[tot].to=v,e[tot].next=head[u],head[u]=tot;
}
void init(){
	int i,u,v;
	scanf("%d",&n);
	for(i=1;i<=n;i++)scanf("%d%d%d",&a[i],&b[i],&c[i]);
	for(i=1;i<n;i++)scanf("%d%d",&u,&v),add_edge(u,v),add_edge(v,u);
}
void dfs(int u,int fa,int cost){//注意:数据的传入是自顶向下
	int p,v;
	cost=min(cost,a[u]);//此步很神奇,避免了排序代码
	if(b[u]==0&&c[u]==1)f[u]=1;
	if(b[u]==1&&c[u]==0)g[u]=1;
	for(p=head[u];p;p=e[p].next){
		v=e[p].to;
		if(v==fa)continue;
		dfs(v,u,cost);
		f[u]+=f[v];
		g[u]+=g[v];
	}
	int num=min(f[u],g[u]);
	ans+=(LL)cost*num*2;//注意,数据的处理是自底向上
	f[u]-=num,g[u]-=num;//此步很神奇,避免了单独再写的更新代码
}
void solve(){
	if(f[1]||g[1]){printf("-1\n");return;}//匹配未成功
	printf("%lld\n",ans);
}
int main(){
	init();
	dfs(1,0,INF);
	solve();
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值