首页 > 其他分享 >CF1468J Road Reform 题解

CF1468J Road Reform 题解

时间:2024-03-24 12:55:25浏览次数:20  
标签:CF1468J int 题解 最大值 ans 生成 max 条边 Road

题目简述

给定一个有 $n$ 个节点,$m$ 条无向带权边的图,和一个参数 $k$,第 $i$ 条边权值为 $s_i$。

现在你要保留这个图中的 $n-1$ 条边使得这个图变成一棵树,然后你可以对这棵树上的任意边进行修改,每次修改可以使这个边的权值加上一或减去一。

现在你需要使所有边权的最大值正好等于 $k$,求所有保留方案的最小操作数。

题目分析

首先,发现此题要求的是最大值等于 $k$,易想到先做出最小的情况,再调整最大值逼近 $k$,并且本题还要将一张图变成一棵树,综上所述,可以想到先求出图的最小生成树。

接下来,我们可知最小生成树的最大值,令它为 $\max$,我们可分以下三种情况尽行讨论:

  • 如果 $\max\lt k$,我们可以遍历所有的边,找一条最接近 $k$ 的边,他们之间的差的绝对值便是答案。由生成树的性质可知,使这条边替换生成树的一条边后生成树仍然可以是一棵树,符合题意。
  • 如果 $\max=k$,不需要调整,答案为 $0$。
  • 如果 $\max\gt k$,我们应遍历所有树边,将凡是大于 $k$ 的树边都减小使它等于 $k$,并累加他们的差,这样才能符合要求。由于是最小生成树,易证此为最优解。

代码

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int n,m,t,k,fu[N],Max,a[N],b[N],cnt1;
unsigned long long ans;
struct edge
{
	int u,v,w;
	friend bool operator < (edge x,edge y)
	{
		return x.w<y.w;
	}
}e[N];
int find(int x)
{
	return fu[x]==x?x:fu[x]=find(fu[x]);
}
void solve()
{
	cin>>n>>m>>k;
	cnt1=0;
	ans=-1;
	memset(e,0,sizeof e);
	memset(fu,0,sizeof fu);
	for(int i=1;i<=n;i++)
	{
		fu[i]=i;
	}
	for(int i=1;i<=m;i++)
	{
		cin>>e[i].u>>e[i].v>>e[i].w;
	}
	sort(e+1,e+1+m);
	for(int i=1;i<=m;i++)
	{
		int x=e[i].u,y=e[i].v;
		if(find(x)!=find(y))
		{
			fu[find(x)]=find(y);
			Max=e[i].w;
			b[++cnt1]=e[i].w;
		}
		a[i]=e[i].w;
	}
	if(Max<k)
	{
	    for(int i=1;i<=m;i++)
	    {
	    	ans=min(ans,1ull*abs(k-a[i]));
		}
	}
	else
	{
		ans=0;
		for(int i=1;i<=cnt1;i++)
		{
			if(b[i]>=k) ans+=b[i]-k;
		}
	}
    cout<<ans<<"\n";
}
int main()
{
	cin>>t;
	while(t--)
	{
		solve();
	}
	return 0;
}

标签:CF1468J,int,题解,最大值,ans,生成,max,条边,Road
From: https://www.cnblogs.com/zhuluoan/p/18092286

相关文章

  • 20240323每日一题题解
    20240323每日一题题解Problem输出2024是十二生肖中的哪个动物年?(只需要输出排行第几即可)鼠视为十二生肖中的第一位。注意:答案输出为阿拉伯数字。Solution首先,我要感谢班长在百忙之中选择了这样的一道题,让我在不是周末的周日能够抽出时间水题解报告。你说的对,但是《原神》......
  • CF1628D1 Game on Sum (Easy Version) 题解
    题目传送门(EasyVersion)|题目传送门(HardVersion)前置知识博弈论解法CF1628D1GameonSum(EasyVersion)设\(x_{i}\)表示第\(i\)轮时Alice选择的数。设\(f_{i,j}\)表示已经进行了\(i\)轮,且使用了\(j\)次加法时的最大得分,状态转移方程为\(f_{i,j}=\ma......
  • codeforces div_2 936 题解报告
    codeforcesdiv_2936题解报告比赛链接:https://codeforces.com/contest/1946A.MedianofanArray做法tag:签到题目翻译给定一个长度为\(n\)的数组\(a\),记数组中非降序排列中第\({\lceil\fracn2\rceil}\)个数是数组a的中位数。我们可以以下操作。选择一个数\(i\in[......
  • CF494C Helping People 题解
    题目传送门前置知识概率DP|树形DP|RMQ解法观察到区间只有相离或包含关系,类似线段树的管辖区间,考虑将其构成树形关系。为方便代码书写,将原来的森林构成一棵树,即增加一个区间\(l_{q+1}=1,r_{q+1}=n,p_{q+1}=0\)。由于对于一个区间\([l,r]\)的最大值在经历任意次操作后,......
  • CF922E Birds 题解
    题目传送门前置知识背包DP解法观察到\(w\)极大,若使用正常的背包空间会爆炸。依据AT_dp_eKnapsack2的经验,考虑将背包“反”着用。设\(f_{i,j}\)表示到第\(i\)棵树时一共召唤了\(j\)只小鸟时剩余的最大魔力值,状态转移方程为\(f_{i,j}=\min(\max\limits_{k=0}^{\m......
  • [暴力题解系列] 2023年蓝桥杯-冶炼金属
    世界上存在很难的题,但不存在暴力偷不到分的题​ 这题的暴力思路比你想的更简单,我直接枚举v的数值不就行了?#include<iostream>#include<algorithm>usingnamespacestd;inta[10010],b[10010];intmain(){intn;scanf("%d",&n);for(inti=1;i<=n;i++)......
  • P10268 符卡对决 题解
    题目链接:符卡对决视频讲解待上传经典的题目,对于这个\([l,r]\)询问,我们先关注期望怎么算。考虑方案总数和有效的和,方案总数显然有\(\dfrac{n\times(n-1)}{2}\),现在还需要关注有效和,我们关注对于若干个有效的关系用一个比较形象的数据结构表示-----并查集,那么两个卡牌之间有......
  • CF1711B Party 题解
    CF1711BParty原题题意给定$n$个点带点权的无向图,点权$a_i$保证无重边自环,点权非负),要求删去一些点和它相连的边,使得剩下这个图的边数为偶数且删去点的点权之和最小。问删去点的点权之和最小是多少?分类讨论我们分类讨论一下。$m$为偶数,则不需要删边或点,直接输出$0$即......
  • 洛谷P3498 [POI2010] KOR-Beads 题解
    P3498[POI2010]KOR-Beads对于数列${A_i}$,求$k$使数列被分为$\lfloor\frac{n}{k}\rfloor$个部分后不同子数列种类最多(子串翻转前后为一类子串)很容易想到:枚举$k\\in\[1,n]$,记录每个$k$下不同种类数,然后取最优即可,那么问题来了:如何计算种类数?暴戾算法:一种纯......
  • 跳马【华为OD机试JAVA&Python&C++&JS题解】
    一.题目马是象棋(包括中国象棋和国际象棋)中的棋子,走法是每步直一格再斜一格,即先横着或直着走一格,然后再斜着走一个对角线,可进可退,可越过河界,俗称“马走‘日’字。给顶m行n列的棋盘(网格图),棋盘上只有有棋子象棋中的棋子“马”,并且每个棋子有等级之分,等级为k的马可以跳1~k......