首页 > 其他分享 >Codeforces Round #813 (Div. 2) - D. Empty Graph

Codeforces Round #813 (Div. 2) - D. Empty Graph

时间:2022-09-21 23:57:56浏览次数:86  
标签:min int Graph Codeforces 最小 权值 INF include Div

构造

Problem - D - Codeforces

题意

给 \(n(1<=n<=10^5)\) 个点,与权值 \(a_i\),这 \(n\) 个点组成一个完全图,\(a_l\) 与 \(a_r\) 连的边的权值为 \(min(a_l,a_{l+1}...a_{r-1},a_r)\)

有 \(k\) 次机会可以把任意一个点的权值变为 INF,求 k 次操作后这个图的直径的最大值

图的直径为任意两个点的最短路中,最长的那一条

思路

  1. 对于两个点 \(l,r\) 的最短路,要么直接从 l 走到 r,为 \([l,r]\) 的最小值;要么 l 到权值最小的点 t 再到 r,为 \(2*a_t\)

    因此直径只可能在 \(a_i,a_{i+1}\) 取到

  2. 直径有两种情况得到,一种是在最大的 \(min(a_i,a_{i+1})\) 取到;一种是在 2 倍最小权值取到

    1. 希望在 \(min(a_i,a_{i+1})\) 取到

    可以先花 k - 1 次让前 k - 1 小的权值变成 INF,留 1 次是因为可能操作 k - 1 次后所有 INF 的位置都是不相邻的,\(min(a_i,a_{i+1})\) 取不到 INF,最后一次让某一项 INF 旁边的变成 INF,这样最大的 \(min(a_i,a_{i+1})\) 就可以取到 INF了;再与 2 倍最小权值取 min

    1. 希望在 2 倍最小权值取到

      直接花 k 次让最小的 k 个权值都变成 INF,再枚举 \(min(a_i,a_{i+1 })\), 求出 2 倍最小权值与最大的 \(min(a_i,a_{i+1 })\) 的最小值

    两者取 max 即为答案

思路 2 比思路 1 优在最小权值更大,但可能最大的 \(min(a_i,a_{i+1})\) 不够大

思路 1 比思路 2 优在最大的 \(min(a_i,a_{i+1})\) 达到了 INF,可以不用考虑这条路了

代码

#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>

using namespace std;
#define endl "\n"

typedef long long ll;
typedef pair<int, int> PII;

const int N = 1e5 + 10;
const int INF = 1e9;
struct Node
{
	int val, id;
	bool operator<(const Node &x) const
	{
		return val < x.val;
	}
}b[N];
int a[N];
int n, k;

int solve()
{
	for (int i = 1; i <= n; i++)
		b[i] = {a[i], i};
	sort(b + 1, b + n + 1);
	for (int i = 1; i < k; i++)
	{
		b[i].val = INF;
		a[b[i].id] = INF;
	}
	sort(b + 1, b + n + 1);
	int ans, ans1 = INF, ans2 = INF;
	ans1 = min(b[1].val * 2, b[n].val);

	b[1].val = INF;
	a[b[1].id] = INF;
	sort(b + 1, b + n + 1);
	ans2 = min(ans2, b[1].val * 2);
	for (int i = 1; i <= n; i++)
		a[b[i].id] = b[i].val;
	int tmp = -INF;
	for (int i = 1; i < n; i++)
		tmp = max(tmp, min(a[i], a[i+1]));
	ans2 = min(ans2, tmp);
	ans = max(ans1, ans2);
	return ans;
}
int main()
{
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int T;
	cin >> T;
	while(T--)
	{
		cin >> n >> k;
		for (int i = 1; i <= n; i++)
			cin >> a[i];
		cout << solve() << endl;
	}
    return 0;
}

标签:min,int,Graph,Codeforces,最小,权值,INF,include,Div
From: https://www.cnblogs.com/hzy717zsy/p/16717673.html

相关文章

  • Codeforces Round #821 (Div. 2) D E
    E首先发现无论何时,每个位置上至多只会有一个球。原因:每个时刻每个球都会移动,所以移动到某个点的时间一定,自然出生时间也一定,显然不可能会有2个点出生时间相同。既然如......
  • Educational Codeforces Round 119 E
    E.ReplacetheNumbers开始想到了一个二分的做法好像是O(nlog)的后来才想了一下可以在两个数组之间反复横跳那我是不是像记忆化搜索一样记录一个路径即可我们记录f[i]......
  • 监听div高度宽度的变化-自定义指令
    上篇内容说到,iframe嵌入其他项目页面,iframe实现自适应高度需要监听div页面高度的变化使用到了局部自定义指定directives:{//使用局部注册指令的方式resize:{//......
  • Codeforces Round #818 (Div. 2) - D. Madoka and The Corruption Scheme
    思维+组合数学Problem-D-Codeforces题意有\(2^n\)个人进行锦标赛,编号1~\(2^n\),每一场输的人失去比赛资格,赢的人继续。Madoka可以选择他们进行的顺序,以及决定哪一......
  • 在 CSS 中使 div 居中的 5 种方法
    在CSS中使div居中的5种方法5waystocenteradivinCSS你觉得很难在CSS中将div居中吗?你并不孤单,我的兄弟,许多开发人员有时会在将div居中时感到困惑,包括......
  • Codeforces 821 Div2
    T1:大小为n的数组,最多进行k次操作:下标模k意义下相等则可进行交换。求操作后连续k个元素的最大值固定最大值的k个连续因素小标为[0,k),现在只需使得它为最大即可,将可交换位......
  • img和div之间有间隙的原因及解决方法
    div中存在img标签,由于img标签的display:inline-block属性。#####display:inline-block布局的元素在chrome下会出现几像素的间隙,原因是因为我们在编辑器里写代码的......
  • Codeforces Round #821 (Div. 2) - D2. Zero-One (Hard Version)
    区间DPProblem-D2-Codeforces题意给一个长度为\(n(5<=n<=5000)\)的01串,每次操作可选择一个\(l,r(l<r)\),把\(s[l],s[r]\)反转。如果\(l+1==r\),花费为x,否......
  • Codeforces Round #807 (Div. 2) - D. Mark and Lightbulbs
    思维Problem-D-Codeforces题意给两个长度为\(n(3<=n<=2*10^5)\)的01串s与t,求最小操作次数,使s变成t;不存在则输出-1操作为:对于2<=i<=n-1,若\(s_......
  • Codeforces Round #820 (Div. 3) G. Cut Substrings
    DPProblem-G-Codeforces题意给一个长度为\(n(1<=n<=500)\)的主串s,一个长度为\(m(1<=m<=500)\)的模式串t,每次可以将当前的s中与t相同的子串变成一串"."(如......