CodeForces - 191C - Fools and Roads (LCA)

本文介绍了一道 CodeForces 平台上的竞赛题 191C 的解题思路及代码实现。题目要求计算树形结构中每条边被若干路径覆盖的次数。通过记录每个节点到根节点路径上的权值,利用一次深度优先搜索(DFS)将权值分配给各条边。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://codeforces.com/problemset/problem/191/C

题目

给出一棵n个节点的树,还有树上的k条简单路径(用路径的两个端点u和v表示),求树上的各条边被这些简单路径经过的总次数。

题解

只要记录一下每个节点i到根节点路径上所有边都需要加的权值sum[i]就行了。
对于每一组(u,v),题意操作转化为 c[u]++ , a[v]++ , a[ lca(u,v) ] - =2。
最后用一遍dfs把sum拆开

#include<bits/stdc++.h>
using namespace std;
int to[400010],h1[400010],h2[400010],cnt,next[400010];
int f[400010],a[400010],c[400010];
void add(int head[],int u,int vv)
{
	cnt++;
	to[cnt]=vv;
	next[cnt]=head[u];
	head[u]=cnt;
}
int find(int x)
{
	return x==f[x]?x:f[x]=find(f[x]);
}
void ddd(int x)
{
	f[x]=x;
	for(int i=h2[x]; i!=0; i=next[i])
	{
		a[x]++;
		if(f[to[i]]) a[find(to[i])]-=2;
	}
	for(int i=h1[x]; i!=0; i=next[i])
	{
		if(f[to[i]]==0)
		{
			ddd(to[i]);
			a[x]+=c[i+1>>1]=a[to[i]];
			f[to[i]]=x;
		}
	}
}
int main()
{
//	freopen("a.txt","r",stdin);
	int n,i,m,x,y;
	cnt=0;
	scanf("%d",&n);
	for(i=1; i<n; i++)
	{
		scanf("%d%d",&x,&y);
		add(h1,x,y);
		add(h1,y,x);
	}
	scanf("%d",&m);
	for(i=1; i<=m; i++)
	{
		scanf("%d%d",&x,&y);
		if(x==y) continue;
		add(h2,x,y);
		add(h2,y,x);
	}
	ddd(1);
	for(i=1; i<n; i++) printf("%d ",c[i]);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值