首页 > 其他分享 >蓝桥杯2023年第十四届省赛A组-网络稳定性

蓝桥杯2023年第十四届省赛A组-网络稳定性

时间:2024-10-05 13:18:32浏览次数:9  
标签:std yi int father 稳定性 蓝桥 fa 2023 省赛

题目描述

有一个局域网,由 n 个设备和 m 条物理连接组成,第 i 条连接的稳定性为wi 。

对于从设备 A 到设备 B 的一条经过了若干个物理连接的路径,我们记这条路径的稳定性为其经过所有连接中稳定性最低的那个。

我们记设备 A 到设备 B 之间通信的稳定性为 A 至 B 的所有可行路径的稳定性中最高的那一条。

给定局域网中的设备的物理连接情况,求出若干组设备 xi 和 yi 之间的通信稳定性。如果两台设备之间不存在任何路径,请输出 −1 。

输入格式

输入的第一行包含三个整数 n, m, q ,分别表示设备数、物理连接数和询问数。

接下来 m 行,每行包含三个整数 ui , vi ,wi ,分别表示 ui 和 vi 之间有一条稳定性为 wi 的物理连接。

接下来 q 行,每行包含两个整数 xi , yi ,表示查询 xi 和 yi 之间的通信稳定性。

输出格式

输出 q 行,每行包含一个整数依次表示每个询问的答案。

样例输入

5 4 3
1 2 5
2 3 6
3 4 1
1 4 3
1 5
2 4
1 3

样例输出

-1
3
5

提示

对于 30% 的评测用例,n, q ≤ 500,m ≤ 1000 ;

对于 60% 的评测用例,n, q ≤ 5000,m ≤ 10000 ;

对于所有评测用例,2 ≤ n, q ≤ 10^5,1 ≤ m ≤ 3 × 10^5,1 ≤ ui , vi , xi , yi ≤ n,1 ≤ wi ≤ 10^6, ui ≠ vi,xi ≠ yi 。

暴力解法

使用 Floyd 算法

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;

const int N = 5e3 + 5;
int e[N][N];
int n, m, q;

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	cin >> n >> m >> q;
	for(int i = 1; i <= n; i++)
	{
		for(int j = 1; j <= n; j++)
		{
			if(i == j)
			{
				e[i][j] = 0;
			}
			else
			{
				e[i][j] = -1;
			}
		}
	}
	for(int i = 1; i <= m; i++)
	{
		int u, v, w;
		cin >> u >> v >> w;
		e[u][v] = max(e[u][v], w);
		e[v][u] = max(e[v][u], w);
	}
	for(int k = 1; k <= n; k++)
	{
		for(int i = 1; i <= n; i++)
		{
			for(int j = 1; j <= n; j++)
			{
				if(i != j && j != k && k != i)
				{
					e[i][j] = max(e[i][j], min(e[i][k], e[k][j]));
				}
			}
		}
	}
	for(int i = 1; i <= q; i++)
	{
		int x, y;
		cin >> x >> y;
		cout << e[x][y] << endl;
	}
	return 0;
}

整体思路

使用 Kruskal 重构树,再用倍增法 LCA 寻找最大生成树的最近公共祖先。

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;

const int N = 2e5 + 5;
const int M = 3e5 + 5;
int father[N << 1], val[N << 1];
vector<int> edge[N << 1];
int dep[N << 1], fa[N << 1][25], lg[N << 1];
struct node
{
	int u;
	int v;
	int dis;
}e[M];
int n, m, q;

bool cmp(node x, node y)
{
	return x.dis > y.dis;
}

int findfather(int v)
{
	if(father[v] == v)
	{
		return v;
	}
	else
	{
		int F = findfather(father[v]);
		father[v] = F;
		return F;
	}
}

void Kruskal()
{
	for(int i = 1; i < 2 * n; i++)
	{
		father[i] = i;
	}
	sort(e + 1, e + 1 + m, cmp);
	int idx = n; // 新建节点的编号 
	for(int i = 1; i <= m; i++)
	{
		int fu = findfather(e[i].u);
		int fv = findfather(e[i].v);
		if(fu != fv)
		{
			val[++idx] = e[i].dis;
			edge[idx].push_back(fu);
			edge[idx].push_back(fv);
			father[fu] = father[fv] = idx;
		}
	}
}

void dfs(int u, int father)
{
	dep[u] = dep[father] + 1;
	fa[u][0] = father;
	for(int i = 1; i <= lg[dep[u]]; i++)
	{
		fa[u][i] = fa[fa[u][i - 1]][i - 1];
	}
	for(int v : edge[u])
	{
		if(v != father)
		{
			dfs(v, u);
		}
	}
}

int lca(int u, int v)
{
	if(findfather(u) != findfather(v))
	{
		return -1;
	}
	if(dep[u] < dep[v])
	{
		swap(u, v);
	}
	for(int i = lg[dep[u] - dep[v]] - 1; i >= 0; i--)
	{
		if(dep[fa[u][i]] >= dep[v])
		{
			u = fa[u][i];
		}
	}
	if(u == v)
	{
		return val[u];
	}
	for(int i = lg[dep[u]] - 1; i >= 0; i--)
	{
		if(fa[u][i] != fa[v][i])
		{
			u = fa[u][i];
			v = fa[v][i];
		}
	}
	return val[fa[u][0]];
}

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	cin >> n >> m >> q;
	for(int i = 1; i <= m; i++)
	{
		int u, v, w;
		cin >> u >> v >> w;
		e[i].u = u;
		e[i].v = v;
		e[i].dis = w;
	}
	for(int i = 1; i <= 2 * n; i++)
	{
		lg[i] = lg[i - 1] + ((1 << lg[i - 1]) == i);
	}
	
	Kruskal();
	for(int i = 1; i < 2 * n; i++)
	{
		if(father[i] == i)
		{
			dfs(i, 0);
		}
	}
	
	while(q--)
	{
		int x, y;
		cin >> x >> y;
		cout << lca(x, y) << endl;
	}
	return 0;
}

标签:std,yi,int,father,稳定性,蓝桥,fa,2023,省赛
From: https://blog.csdn.net/hehe_666888/article/details/142712717

相关文章

  • 蓝桥杯2024年第十五届省赛A组-有奖问答
    题目描述小蓝正在参与一个现场问答的节目。活动中一共有30道题目,每题只有答对和答错两种情况,每答对一题得10分,答错一题分数归零。小蓝可以在任意时刻结束答题并获得目前分数对应的奖项,之后不能再答任何题目。最高奖项需要100分,所以到达100分时小蓝会直接停止答题。......
  • At_pakencamp_2023_day1_p sol
    题面给你两个序列\(A,B\),\(\forallu,v(u\not=v)\)之间边的权值为\(a_ua_v+b_ub_v\)。求最小生成树的边权和。原题目editorial朴素的想法考虑类似题目的做法,考虑每一次寻找最小的然后加入。发现这种思想和Boruvka比较相似。于是我们考虑Boruvka的方式来做。对现有的连......
  • 【真题研究】春季测试 2023
    T1.涂色游戏(paint)可以按照题意模拟,每一次暴力对于每一行列染色,时间复杂度\(O(qn)\)。可得60pts。因为颜色可以覆盖,某一格的颜色往往取决于最后一次被染到的颜色。于是我们采用打标记的方式。每一次染色(行或列)就在当前行列打标记,记操作时间戳\(t\)。最后输出答案时枚举每一格......
  • [CSP-J 2023] 小苹果(apple)-----------用数组
    1#include<iostream>2usingnamespacestd;3intmain(){4intn,m;5cin>>n>>m;6intg=n,t=0,li,s[n+1],b;7for(inti=1;i<=n;i++){8s[i]=i;9}10while(g){11t+=1,b=0,li=0,g-=(g+......
  • 【极客大挑战2023】- Re -点击就送的逆向题 WriteUp
    这道题给了一个.s文件解决方案有两个:1.利用gcc编译成可执行文件,然后反编译生成伪代码2.直接分析汇编(我不会。。。)1.利用gcc编译成可执行文件linux执行gcc-o1.s1IDA打开,分析并编写,注意一定要在字符串末尾加上\0结束符!!!点击查看代码#include<stdio.h>intmain(void){......
  • 2023ICPC 沈阳
    赛时5题xixike仍然是平衡树大神。gxd仍然是计数大神。而我签了三个到下班。c题签到,略J:结论题E:bfs的一个dp,第一次写写了比较久K:xixike平衡树过的。赛后补题的时候我先是写了一个双log动态开点权值线段树,然后别人教我线段树二分到了单log。但是直接离散化不动态开点的......
  • 【极客大挑战2023】RE方向 WriteUp
    1.砍树下载题目得到一个apk文件,jadx打开,查看Android.Manifest.xml查看MainActivity发现使用了一个I0o0I处理了输入和Syclover,猜测应该是对text处理后与Syclover对比,当result赋值为1就成功了。故查看I0o0I发现I0o0I再so文件中,故查看libezreeeee.so文件IDA打开,查找I0o0I生......
  • P9752 [CSP-S 2023] 密码锁&&P8814 [CSP-J 2022] 解密
    GutenTag!Schön,dichzusehen!今天也是很懒惰的一天呢!所以今天三合一!题目:[CSP-S2023]密码锁题目描述小Y有一把五个拨圈的密码锁。如图所示,每个拨圈上是从$0$到$9$的数字。每个拨圈都是从$0$到$9$的循环,即$9$拨动一个位置后可以变成$0$或$8$,因为校园里......
  • 2023-12-15 博士挑战--达成 113823
    目录现状改进未来现状这个世界最神奇的,莫过于永远都有意外,第二步以和平的地方式提前达成了。1.意外一:迫于各种压力(我的态度、项目进度、其他学者进展、外界评价),导师已于上周开始给师姐改论文并尽快投出去。这结局是最好的,只是有点过早。2.意外二:没想到师妹论文写得太不勤快了,......
  • 2023-12-15 博士挑战--落幕 123744
    目录总纲现状反思未来总纲宇宙万物、世间一切自有因果。自助者天助,然若不自助,神明亦爱莫能助。人的好坏定义并非从言行举止来衡量,而是有无执着。现状老师不再执着于己见--要求他的所有学生都成为有声望的学者。我目前一切都好,正在做想做的理论方向且成就感满满,工资上涨,......