首页 > 其他分享 >AtCoder Beginner Contest 355(F - MST Query)

AtCoder Beginner Contest 355(F - MST Query)

时间:2024-05-26 18:31:47浏览次数:23  
标签:AtCoder Beginner Contest fas 边权 leq quad ll 10

很久没有见到这么好的题了。

原题面

用 C h a t G P T − 4 o ChatGPT-4o ChatGPT−4o翻译好的题面:

你被给定一个带权无向连通图 G G G,它有 N N N 个顶点和 N − 1 N-1 N−1 条边,顶点编号为 1 1 1 到 N N N,边编号为 1 1 1 到 N − 1 N-1 N−1。边 i i i 连接顶点 a i a_i ai​ 和 b i b_i bi​,权重为 c i c_i ci​。

给定 Q Q Q 个查询需要顺序处理。第 i i i 个查询描述如下:

给定整数 u i , v i , w i u_i, v_i, w_i ui​,vi​,wi​。在 G G G 中添加一条权重为 w i w_i wi​ 的边连接顶点 u i u_i ui​ 和 v i v_i vi​。然后,打印 G G G 的最小生成树的边权和。

约束条件

  • 2 ≤ N ≤ 2 × 1 0 5 2 \leq N \leq 2 \times 10^5 2≤N≤2×105
  • 1 ≤ Q ≤ 2 × 1 0 5 1 \leq Q \leq 2 \times 10^5 1≤Q≤2×105
  • 1 ≤ a i < b i ≤ N 1 \leq a_i < b_i \leq N 1≤ai​<bi​≤N
  • 1 ≤ u i < v i ≤ N 1 \leq u_i < v_i \leq N 1≤ui​<vi​≤N
  • 1 ≤ c i , w i ≤ 10 1 \leq c_i, w_i \leq 10 1≤ci​,wi​≤10

图在处理查询之前是连通的。

所有输入值均为整数。

建议还是到原题面看看样例的图。

讲解

通过数据范围发现所有边的边权都在 10 10 10 以内,那么就尝试以边权为突破口。

这里有一个显著结论:

  • 当只考虑边权为 1 1 1 的边时,如果加入这条边没有形成环。那么这条边一定会一直在 M S T (最小生成树) MST(最小生成树) MST(最小生成树) 里。

接下来考虑边权只有 1 1 1 和 2 2 2 的情况(按照边出现的时间顺序考虑)。

如果当前的边的边权为 1 1 1 ,且在只考虑边权为 1 1 1 的边时加入当前边不构成环,但在考虑边权有 1 1 1 和 2 2 2 的情况下加入当前边构成环,说明这条边最终在MST中,而且还替代掉了一个边权为 2 2 2 的边。

我也知道抽象,所以来看图。

假设有三个点,三条边:

格式:端点1 \quad 端点2 \quad 边权

第一条: 1 2 1 1 \quad 2 \quad 1 121

第二条: 2 3 2 2 \quad 3 \quad 2 232

第三条: 1 3 1 1 \quad 3 \quad 1 131

如果我们只考虑边权为 1 1 1 的边,那么图是这样的(没有画第二条边):

在这里插入图片描述
如果我们考虑边权为 1 1 1 和 2 2 2 的边,那么图是这样的:

在这里插入图片描述
在尝试插入第三条边的时候会发现如果插入这条边就会有环,所以要替代掉第二条边,在代码实现的时候在这里记录一下:有一条边权为 2 2 2 的边变为了边权为 1 1 1 的边,最后输出答案的时候做一下前缀和就行了。

对于其他边权的边也同理。

其中 f l a g flag flag 用来判断上一轮结束的时候这条边有没有在 M S T (最小生成树) MST(最小生成树) MST(最小生成树) 中。

配合 D S U (并查集) DSU(并查集) DSU(并查集) 写出代码,还有一些没有将的放到代码注释里了。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,m,a[400005],b[400005],c[400005],fas[200005],flag[400005],dp[400005];
inline ll fid(ll p){
	if(p!=fas[p])fas[p]=fid(fas[p]);
	return fas[p];
}
inline void miker(ll x,ll y){
	x=fid(x);y=fid(y);
	fas[x]=y;
}
signed main(){
	ios::sync_with_stdio(false);
	cin>>n>>m;
	for(ll i=1;i<n+m;i++)cin>>a[i]>>b[i]>>c[i];
	for(ll q=1;q<=10;q++){
		for(ll i=1;i<=n;i++)fas[i]=i;
		for(ll i=1;i<n+m;i++){
			if(c[i]>q)continue;
			if(fid(a[i])!=fid(b[i])){
				miker(a[i],b[i]);
				if(!flag[i]){
					dp[i]+=q;
					flag[i]=1;
				}
			}
			else if(flag[i]){
				// 为什么替代调的边的边权一定是 q ,因为在之前的循环中已经把 边权<q 的边能替换的都替换掉了。 
				dp[i]-=q;
				
				// 因为后面要求前缀和,所以这里要把 flag 变为 0 ,否则会重复计算。 
				flag[i]=0;
			}
		}
	}
	ll ans=0;
	for(ll i=1;i<n+m;i++){
		ans+=dp[i];
		if(i>=n)cout<<ans<<endl;
	}
	return 0;
}

总结方法

  1. 在做题是可以考虑通过数据范围寻找突破口。

  2. 在动态加边的题中可以考虑用前缀和。

最后,希望大家可以把不懂的地方在评论区或私信说出来,也希望可以指出我的错误。我会尽量在12小时内回答。

求点赞、关注、收藏。

标签:AtCoder,Beginner,Contest,fas,边权,leq,quad,ll,10
From: https://blog.csdn.net/MC_wansui/article/details/139216836

相关文章

  • Tokio Marine & Nichido Fire Insurance Programming Contest 2024(AtCoder Beginner C
    A-WhoAtetheCake?题意:有三个嫌疑犯(1,2,3(号码))现在有两个证人他们指出谁不是嫌疑犯,你可以找到确定的那个罪人吗?找到输出这个人的号码没找到输出-1思路:如果两人指出的人是一个人则输出-1不是则输出6-a-b,因为1+2+3=6(sum)减去a,b肯定可以到达......
  • D - AtCoder Wallpaper(求图形面积)
    思路:求f(c,d)+f(a,b)-f(a,d)-f(c,b);代码:intf(intx,inty){if(y%2==0){y=y/2;intans=y*(x/4)*8;x%=4;if(x==1){ans+=y*3;}elseif(x==2){ans+=y*6......
  • Atcoder 题目选做(五)
    \(\text{ByDaiRuiChen007}\)1.[ARC159E]DifferenceSumQueryProblemLink给定\(n,m\),定义\(x\in[1,n]\)的深度\(f(x)\)为:初始\([l,r]=[1,n]\)。第\(i\)次操作求出\(l,r\)按\(a_{i\bmodm}:b_{i\bmodm}\)的比例的中点\(mid\)。如果\(x=mid\),那么......
  • Atcoder 题目选做(六)
    \(\text{ByDaiRuiChen007}\)1.[ARC162E]StrangeConstraintsProblemLink给定\(a_1\sima_n\),求有多少\(b_1\simb_n\)满足:\(b_i\in[1,n]\),且\(i\)和\(b_i\)的出现次数均不超过\(a_i\)。数据范围:\(n\le500\)。设\(\gek\)的\(a_i\)有\(c_k......
  • Atcoder 题目选做(四)
    \(\text{ByDaiRuiChen007}\)1.[AGC059C]GuessingPermutationforasLongasPossibleProblemLink给定\(\dfrac{n\times(n-1)}2\)个\([1,n]\)中的二元对的顺序,求有多少个\(n\)阶排列\(P\)使得按顺序询问到每个\((u,v)\)之前无法确定\(P_u,P_v\)大小关系......
  • ABC 354 (atcoder beginer 354) D、E、F
     D 检查:1.有可能是推导式有问题,比如-/+写错2.x,yA、B、C、D顺序可能搞反了不要盲目调试,先用人眼看一下代码的情况,找一下错误 很简单的找规律的题目。很不能理解过的人,就这些。x方向,y方向,都是4行/列,一个规律的循环。 求(0,0)到(x,y)中的黑色块:第0-3行分别求出黑色......
  • Godot Breakeys Godot Beginner Tutorial 游戏开发笔记
    目录前言资源下载添加人物节点运动状态机移动平台单向穿过奇怪的BugArea2DBodyEntered死亡区域全局类多线程安全TileMap处理TileMap分层前言这次来学习一下youtube的传奇Unity博主,Breakeys的Godot新手教程。Breakeys是从15岁左右就开始用unity做游戏并在youtube上面发布视频了。......
  • AtCoder abc354E
    原题链接ProblemStatementTakahashiandAokiareplayingagameusing\(N\)cards.Thefrontsideofthe\(i\)-thcardhas\(A_i\)writtenonit,andthebacksidehas\(B_i\)writtenonit.Initially,the\(N\)cardsarelaidoutonthetable.Wit......
  • AtCoder Beginner Contest 354
    A-ExponentialPlant(abc354A)题目大意某星球上的植物,初始高\(0\),然后每天依次增长\(1,2,4,8,...\),问哪天就高过身高为\(h\)的高桥。解题思路因为是指数级别长高,枚举一下天数即可,由于\(h\leq10^9\),因此天数不会超过\(32\)天。神奇的代码#include<bits/stdc++.h>u......
  • Codeforces 401B Sereja and Contests 题解
    题目简述Sereja是一名程序员,他喜欢参加Codesorfes比赛。不过,乌兹兰的网络连接不太好,所以Sereja有时会跳过比赛。Codesorfes有两种类型的比赛,分为Div1和Div2。Div1和Div2这两轮可以同时进行(Div1轮不能在没有Div2的情况下进行)。每一轮都有一个唯一的标识符,各轮按......