Codeforces Round #693 (Div. 3)G. Moving to the Capital

这篇文章介绍了如何解决Codeforces Problem-G中的问题,利用广搜计算节点到根节点的距离,通过优先处理距离大的节点,结合dp思想,确保在有限操作下达到每个节点到1号节点的最小距离。关键在于理解操作限制和节点间的跳跃策略。

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

题目链接:Problem - G - Codeforces

题目大意:给定一张n个节点m条边的图,定义d数组为每个结点到结点1的距离。

每次可以选择两个操作:1,跳到结点x,dx>d当前 2.跳到结点x,dx<=d当前

注意:操作2最多只能执行1次。求每个点经过操作后到结点1的最小距离
考察知识点:树的广搜,dp思维

题解:首先我们先对树进行广搜,计算出每个点到根节点的距离,然后我们根据距离从大到小进行遍历。对于父亲结点u和儿子节点v,如果d[u]<d[v],f[u]=min(f[u],f[v])  (f数组为最终答案)。否则

f[u]=min(f[u],d[v]),这里是dv的原因是从距离远的跳到距离近的只能跳一次,跳完以后要往大的更新,所以最后f[v]是要大于f[u]的,那么这里选择dv是正确的。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 10;
vector<int>g[maxn],c[maxn];
int vis[maxn], d[maxn],res[maxn];
void solve()
{
	int n, m;
	cin >> n >> m;
	for (int i = 1; i <= n; i++)
	{
		g[i].clear();
		c[i].clear();
	}
	int x, y;
	for (int i = 1; i <= m; i++)
	{
		cin >> x >> y;
		g[x].push_back(y);
	}
	memset(vis, 0, sizeof(vis));
	queue<int>q;
	q.push(1);
	vis[1] = 1;
	while (q.size())
	{
		int u = q.front();
		q.pop();
		c[d[u]].push_back(u);
		int len = g[u].size();
		for (int i = 0; i < len; i++)
		{
			int v = g[u][i];
			if (vis[v])continue;
			d[v] = d[u] + 1;
			vis[v] = 1;
			q.push(v);
		}
	}
	/*for (int i = 1; i <= n; i++)cout << d[i] << " ";*/
	for (int i = 1; i <= n; i++)res[i] = d[i];
	for (int l = n - 1; l >= 0; --l) {            // 由远到近遍历每一点
		int num = c[l].size();
		for (int i = 0; i < num; ++i) {
			int u = c[l][i];
			int len = g[u].size();
			for (int j = 0; j < len; ++j) {
				int v = g[u][j];
				if (d[u] < d[v]) res[u] = min(res[u], res[v]);
				else res[u] = min(res[u], d[v]);
			}
		}
	}
	for (int i = 1; i <= n; ++i) printf("%d ", res[i]);
	printf("\n");

}
int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		solve();
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

流浪小林

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

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

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

打赏作者

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

抵扣说明:

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

余额充值